#include "llvm/Support/Allocator.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/DebugCounter.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Scalar/GVNExpression.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
STATISTIC(NumGVNNotMostDominatingLeader,
"Number of times a member dominated it's new classes' leader");
STATISTIC(NumGVNDeadStores, "Number of redundant/dead stores eliminated");
-
+DEBUG_COUNTER(VNCounter, "newgvn-vn",
+ "Controls which instructions are value numbered")
//===----------------------------------------------------------------------===//
// GVN Pass
//===----------------------------------------------------------------------===//
// Deletion info.
SmallPtrSet<Instruction *, 8> InstructionsToErase;
+ // The set of things we gave unknown expressions to due to debug counting.
+ SmallPtrSet<Instruction *, 8> DebugUnknownExprs;
public:
static char ID; // Pass identification, replacement for typeid.
NewGVN() : FunctionPass(ID) {
#endif
InstrDFS.clear();
InstructionsToErase.clear();
-
DFSToInstr.clear();
BlockInstRange.clear();
TouchedInstructions.clear();
DominatedInstRange.clear();
MemoryAccessToClass.clear();
PredicateToUsers.clear();
+ DebugUnknownExprs.clear();
}
std::pair<unsigned, unsigned> NewGVN::assignDFSNumbers(BasicBlock *B,
// congruence finding, and updating mappings.
void NewGVN::valueNumberInstruction(Instruction *I) {
DEBUG(dbgs() << "Processing instruction " << *I << "\n");
-
// There's no need to call isInstructionTriviallyDead more than once on
// an instruction. Therefore, once we know that an instruction is dead
// we change its DFS number so that it doesn't get numbered again.
return;
}
if (!I->isTerminator()) {
- const auto *Symbolized = performSymbolicEvaluation(I);
+ const Expression *Symbolized = nullptr;
+ if (DebugCounter::shouldExecute(VNCounter)) {
+ Symbolized = performSymbolicEvaluation(I);
+ } else {
+ // Used to track which we marked unknown so we can skip verification of
+ // comparisons.
+ DebugUnknownExprs.insert(I);
+ }
// If we couldn't come up with a symbolic expression, use the unknown
// expression
if (Symbolized == nullptr)
if (!ReachableBlocks.count(&BB))
continue;
for (auto &I : BB) {
- if (InstructionsToErase.count(&I))
+ if (InstructionsToErase.count(&I) || DebugUnknownExprs.count(&I))
continue;
if (isa<CmpInst>(&I)) {
auto *CurrentVal = ValueToClass.lookup(&I);
--- /dev/null
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; REQUIRES: asserts
+; RUN: opt -S -debug-counter=newgvn-vn-skip=1,newgvn-vn-count=2 -newgvn < %s 2>&1 | FileCheck %s
+;; Test that, with debug counters on, we don't value number the first instruction, only the second and third,
+;; which means we do not discover the return is constant.
+define i32 @vntest() {
+; CHECK-LABEL: @vntest(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[A:%.*]] = add i32 1, 3
+; CHECK-NEXT: [[D:%.*]] = add i32 8, 8
+; CHECK-NEXT: ret i32 [[D]]
+;
+bb:
+ %a = add i32 1, 3
+ %b = add i32 %a, %a
+ %c = add i32 %a, %a
+ %d = add i32 %b, %c
+ ret i32 %d
+}
+
+
+
-; REQUIRES: asserts
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-;; Test that, with debug counters on, we don't rename the first info, only the second
+; REQUIRES: asserts
; RUN: opt -debug-counter=predicateinfo-rename-skip=1,predicateinfo-rename-count=1 -print-predicateinfo -analyze < %s 2>&1 | FileCheck %s
+;; Test that, with debug counters on, we don't rename the first info, only the second
define fastcc void @barney() {
; CHECK-LABEL: @barney(
; CHECK-NEXT: bb:
bb35: ; preds = %bb33, %bb29, %bb22
unreachable
}
-