[llvm] r328015 - [MustExecute] Use the annotation style printer
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 20 11:43:44 PDT 2018
Author: reames
Date: Tue Mar 20 11:43:44 2018
New Revision: 328015
URL: http://llvm.org/viewvc/llvm-project?rev=328015&view=rev
Log:
[MustExecute] Use the annotation style printer
As suggested in the original review (https://reviews.llvm.org/D44524), use an annotation style printer instead.
Note: The switch from -analyze to -disable-output in tests was driven by the fact that seems to be the idiomatic style used in annoation passes. I tried to keep both working, but the old style pass API for printers really doesn't make this easy. It invokes (runOnFunction, print(Module)) repeatedly. I decided the extra state wasn't worth it given the old pass manager is going away soonish anyway.
Modified:
llvm/trunk/lib/Analysis/MustExecute.cpp
llvm/trunk/test/Analysis/MustExecute/loop-header.ll
Modified: llvm/trunk/lib/Analysis/MustExecute.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MustExecute.cpp?rev=328015&r1=328014&r2=328015&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/MustExecute.cpp (original)
+++ llvm/trunk/lib/Analysis/MustExecute.cpp Tue Mar 20 11:43:44 2018
@@ -10,19 +10,19 @@
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/AssemblyAnnotationWriter.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
using namespace llvm;
namespace {
struct MustExecutePrinter : public FunctionPass {
- DenseMap<Value*, SmallVector<Loop*, 4> > MustExec;
- SmallVector<Value *, 4> Ordering;
static char ID; // Pass identification, replacement for typeid
MustExecutePrinter() : FunctionPass(ID) {
@@ -34,11 +34,6 @@ namespace {
AU.addRequired<LoopInfoWrapperPass>();
}
bool runOnFunction(Function &F) override;
- void print(raw_ostream &OS, const Module * = nullptr) const override;
- void releaseMemory() override {
- MustExec.clear();
- Ordering.clear();
- }
};
}
@@ -54,7 +49,7 @@ FunctionPass *llvm::createMustExecutePri
return new MustExecutePrinter();
}
-bool isMustExecuteIn(Instruction &I, Loop *L, DominatorTree *DT) {
+bool isMustExecuteIn(const Instruction &I, Loop *L, DominatorTree *DT) {
// TODO: move loop specific code to analysis
//LoopSafetyInfo LSI;
//computeLoopSafetyInfo(&LSI, L);
@@ -62,41 +57,67 @@ bool isMustExecuteIn(Instruction &I, Loo
return isGuaranteedToExecuteForEveryIteration(&I, L);
}
-bool MustExecutePrinter::runOnFunction(Function &F) {
- auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- for (auto &I: instructions(F)) {
- Loop *L = LI.getLoopFor(I.getParent());
- while (L) {
- if (isMustExecuteIn(I, L, &DT)) {
- if (!MustExec.count(&I))
- Ordering.push_back(&I);
- MustExec[&I].push_back(L);
- }
- L = L->getParentLoop();
- };
+/// \brief An assembly annotator class to print must execute information in
+/// comments.
+class MustExecuteAnnotatedWriter : public AssemblyAnnotationWriter {
+ DenseMap<const Value*, SmallVector<Loop*, 4> > MustExec;
+
+public:
+ MustExecuteAnnotatedWriter(const Function &F,
+ DominatorTree &DT, LoopInfo &LI) {
+ for (auto &I: instructions(F)) {
+ Loop *L = LI.getLoopFor(I.getParent());
+ while (L) {
+ if (isMustExecuteIn(I, L, &DT)) {
+ MustExec[&I].push_back(L);
+ }
+ L = L->getParentLoop();
+ };
+ }
+ }
+ MustExecuteAnnotatedWriter(const Module &M,
+ DominatorTree &DT, LoopInfo &LI) {
+ for (auto &F : M)
+ for (auto &I: instructions(F)) {
+ Loop *L = LI.getLoopFor(I.getParent());
+ while (L) {
+ if (isMustExecuteIn(I, L, &DT)) {
+ MustExec[&I].push_back(L);
+ }
+ L = L->getParentLoop();
+ };
+ }
}
- return false;
-}
-void MustExecutePrinter::print(raw_ostream &OS, const Module *M) const {
- OS << "The following are guaranteed to execute (for the respective loops):\n";
- for (Value *V: Ordering) {
- V->printAsOperand(OS);
- auto NumLoops = MustExec.lookup(V).size();
+
+ void printInfoComment(const Value &V, formatted_raw_ostream &OS) override {
+ if (!MustExec.count(&V))
+ return;
+
+ const auto &Loops = MustExec.lookup(&V);
+ const auto NumLoops = Loops.size();
if (NumLoops > 1)
- OS << "\t(mustexec in " << NumLoops << " loops: ";
+ OS << " ; (mustexec in " << NumLoops << " loops: ";
else
- OS << "\t(mustexec in: ";
+ OS << " ; (mustexec in: ";
bool first = true;
- for (const Loop *L : MustExec.lookup(V)) {
+ for (const Loop *L : Loops) {
if (!first)
OS << ", ";
first = false;
OS << L->getHeader()->getName();
}
- OS << ")\n";
+ OS << ")";
}
- OS << "\n";
+};
+
+bool MustExecutePrinter::runOnFunction(Function &F) {
+ auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
+ auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+
+ MustExecuteAnnotatedWriter Writer(F, DT, LI);
+ F.print(dbgs(), &Writer);
+
+ return false;
}
Modified: llvm/trunk/test/Analysis/MustExecute/loop-header.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/MustExecute/loop-header.ll?rev=328015&r1=328014&r2=328015&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/MustExecute/loop-header.ll (original)
+++ llvm/trunk/test/Analysis/MustExecute/loop-header.ll Tue Mar 20 11:43:44 2018
@@ -1,12 +1,14 @@
-; RUN: opt -analyze -print-mustexecute %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -disable-output -print-mustexecute %s 2>&1 | FileCheck %s
-; CHECK: Printing analysis 'Instructions which execute on loop entry' for function 'header_with_icf':
-; CHECK: The following are guaranteed to execute (for the respective loops):
-; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] (mustexec in: loop)
-; CHECK: %v = load i32, i32* %p (mustexec in: loop)
-; CHECK: call void @maythrow_and_use(i32 %v) (mustexec in: loop)
-; CHECK-NOT: add
define i1 @header_with_icf(i32* noalias %p, i32 %high) {
+; CHECK-LABEL: @header_with_icf(
+; CHECK-LABEL: loop:
+; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] ; (mustexec in: loop)
+; CHECK: %v = load i32, i32* %p ; (mustexec in: loop)
+; CHECK: call void @maythrow_and_use(i32 %v) ; (mustexec in: loop)
+; CHECK-NOT: mustexec
+
entry:
br label %loop
@@ -22,12 +24,13 @@ exit:
ret i1 false
}
-; CHECK: Printing analysis 'Instructions which execute on loop entry' for function 'test':
-; CHECK: The following are guaranteed to execute (for the respective loops):
-; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.next, %next ] (mustexec in: loop)
-; CHECK: %v = load i32, i32* %p (mustexec in: loop)
-; CHECK: br label %next (mustexec in: loop)
-define i1 @test(i32* noalias %p, i32 %high) {
+define i1 @split_header(i32* noalias %p, i32 %high) {
+; CHECK-LABEL: @split_header(
+; CHECK-LABEL: loop:
+; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.next, %next ] ; (mustexec in: loop)
+; CHECK: %v = load i32, i32* %p ; (mustexec in: loop)
+; CHECK: br label %next ; (mustexec in: loop)
+; CHECK-NOT: mustexec
entry:
br label %loop
@@ -45,15 +48,19 @@ exit:
ret i1 false
}
-; CHECK: Printing analysis 'Instructions which execute on loop entry' for function 'nested':
-; CHECK: The following are guaranteed to execute (for the respective loops):
-; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.next, %next ] (mustexec in: loop)
-; CHECK: br label %inner_loop (mustexec in: loop)
-; FIXME: These three are also must execute for the outer loop.
-; CHECK: %v = load i32, i32* %p (mustexec in: inner_loop)
-; CHECK: %inner.test = icmp eq i32 %v, 0 (mustexec in: inner_loop)
-; CHECK: br i1 %inner.test, label %inner_loop, label %next (mustexec in: inner_loop)
+; FIXME: everything in inner loop header should be must execute
+; for outer as well
define i1 @nested(i32* noalias %p, i32 %high) {
+; CHECK-LABEL: @nested
+; CHECK-LABEL: loop: ; preds = %next
+; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.next, %next ] ; (mustexec in: loop)
+; CHECK: br label %inner_loop ; (mustexec in: loop)
+; CHECK-LABEL: inner_loop:
+; CHECK: %v = load i32, i32* %p ; (mustexec in: inner_loop)
+; CHECK: %inner.test = icmp eq i32 %v, 0 ; (mustexec in: inner_loop)
+; CHECK: br i1 %inner.test, label %inner_loop, label %next ; (mustexec in: inner_loop)
+; CHECK-NOT: mustexec
+
entry:
br label %loop
More information about the llvm-commits
mailing list