[SafeStack,NFC] Print liveness for all instrunctions

This commit is contained in:
Vitaly Buka 2020-06-19 00:49:23 -07:00
parent 20b1094a04
commit 306c257b00
3 changed files with 82 additions and 8 deletions

View File

@ -156,7 +156,7 @@ public:
return LiveRange(Instructions.size(), true); return LiveRange(Instructions.size(), true);
} }
void print(raw_ostream &O); void print(raw_ostream &O, bool AllInstructions = false);
}; };
static inline raw_ostream &operator<<(raw_ostream &OS, const BitVector &V) { static inline raw_ostream &operator<<(raw_ostream &OS, const BitVector &V) {

View File

@ -27,6 +27,7 @@
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/FormattedStream.h" #include "llvm/Support/FormattedStream.h"
#include <algorithm>
#include <memory> #include <memory>
#include <tuple> #include <tuple>
@ -297,6 +298,8 @@ void StackLifetime::run() {
class StackLifetime::LifetimeAnnotationWriter class StackLifetime::LifetimeAnnotationWriter
: public AssemblyAnnotationWriter { : public AssemblyAnnotationWriter {
const StackLifetime &SL; const StackLifetime &SL;
bool AllInstructions;
void printInstrAlive(unsigned InstrNo, formatted_raw_ostream &OS) { void printInstrAlive(unsigned InstrNo, formatted_raw_ostream &OS) {
SmallVector<StringRef, 16> Names; SmallVector<StringRef, 16> Names;
for (const auto &KV : SL.AllocaNumbering) { for (const auto &KV : SL.AllocaNumbering) {
@ -316,19 +319,33 @@ class StackLifetime::LifetimeAnnotationWriter
} }
void printInfoComment(const Value &V, formatted_raw_ostream &OS) override { void printInfoComment(const Value &V, formatted_raw_ostream &OS) override {
auto It = llvm::find(SL.Instructions, &V); const Instruction *Instr = dyn_cast<Instruction>(&V);
if (It == SL.Instructions.end()) if (!Instr)
return; // Unintresting. return;
auto ItBB = SL.BlockInstRange.find(Instr->getParent());
if (ItBB == SL.BlockInstRange.end())
return; // Unreachable.
// Find the first instruction after the V.
auto It =
std::upper_bound(SL.Instructions.begin() + ItBB->getSecond().first + 1,
SL.Instructions.begin() + ItBB->getSecond().second,
Instr, [](const Instruction *L, const Instruction *R) {
return L->comesBefore(R);
});
--It;
if (!AllInstructions && *It != Instr)
return;
OS << "\n"; OS << "\n";
printInstrAlive(It - SL.Instructions.begin(), OS); printInstrAlive(It - SL.Instructions.begin(), OS);
} }
public: public:
LifetimeAnnotationWriter(const StackLifetime &SL) : SL(SL) {} LifetimeAnnotationWriter(const StackLifetime &SL, bool AllInstructions)
: SL(SL), AllInstructions(AllInstructions) {}
}; };
void StackLifetime::print(raw_ostream &OS) { void StackLifetime::print(raw_ostream &OS, bool AllInstructions) {
LifetimeAnnotationWriter AAW(*this); LifetimeAnnotationWriter AAW(*this, AllInstructions);
F.print(OS, &AAW); F.print(OS, &AAW);
} }
@ -340,6 +357,6 @@ PreservedAnalyses StackLifetimePrinterPass::run(Function &F,
Allocas.push_back(AI); Allocas.push_back(AI);
StackLifetime SL(F, Allocas, Type); StackLifetime SL(F, Allocas, Type);
SL.run(); SL.run();
SL.print(OS); SL.print(OS, true);
return PreservedAnalyses::all(); return PreservedAnalyses::all();
} }

View File

@ -8,6 +8,8 @@ entry:
; CHECK-NEXT: Alive: <> ; CHECK-NEXT: Alive: <>
%x = alloca i32, align 4 %x = alloca i32, align 4
%y = alloca i32, align 4 %y = alloca i32, align 4
; CHECK: %y = alloca i32, align 4
; CHECK-NEXT: Alive: <>
%z = alloca i32, align 4 %z = alloca i32, align 4
%x0 = bitcast i32* %x to i8* %x0 = bitcast i32* %x to i8*
%y0 = bitcast i32* %y to i8* %y0 = bitcast i32* %y to i8*
@ -102,6 +104,8 @@ entry:
; CHECK-NEXT: Alive: <> ; CHECK-NEXT: Alive: <>
ret void ret void
; CHECK: ret void
; CHECK-NEXT: Alive: <>
} }
define void @h() { define void @h() {
@ -110,6 +114,8 @@ entry:
; CHECK: entry: ; CHECK: entry:
; CHECK-NEXT: Alive: <> ; CHECK-NEXT: Alive: <>
%x = alloca i32, align 16 %x = alloca i32, align 16
; CHECK: %x = alloca i32, align 16
; CHECK-NEXT: Alive: <>
%z = alloca i64, align 4 %z = alloca i64, align 4
%y = alloca i32, align 4 %y = alloca i32, align 4
%x0 = bitcast i32* %x to i8* %x0 = bitcast i32* %x to i8*
@ -171,6 +177,8 @@ entry:
call void @capture64(i64* nonnull %x1) call void @capture64(i64* nonnull %x1)
call void @capture64(i64* nonnull %x2) call void @capture64(i64* nonnull %x2)
br i1 %a, label %if.then, label %if.else4 br i1 %a, label %if.then, label %if.else4
; CHECK: br i1 %a, label %if.then, label %if.else4
; CHECK-NEXT: Alive: <x1 x2>
if.then: ; preds = %entry if.then: ; preds = %entry
; CHECK: if.then: ; CHECK: if.then:
@ -225,7 +233,11 @@ if.end: ; preds = %if.else, %if.then3
if.else4: ; preds = %entry if.else4: ; preds = %entry
; CHECK: if.else4: ; CHECK: if.else4:
; CHECK-NEXT: Alive: <x1 x2> ; CHECK-NEXT: Alive: <x1 x2>
%5 = bitcast i64* %z to i8* %5 = bitcast i64* %z to i8*
; CHECK: %5 = bitcast i64* %z to i8*
; CHECK-NEXT: Alive: <x1 x2>
call void @llvm.lifetime.start.p0i8(i64 -1, i8* %5) call void @llvm.lifetime.start.p0i8(i64 -1, i8* %5)
; CHECK: call void @llvm.lifetime.start.p0i8(i64 -1, i8* %5) ; CHECK: call void @llvm.lifetime.start.p0i8(i64 -1, i8* %5)
; CHECK-NEXT: Alive: <x1 x2 z> ; CHECK-NEXT: Alive: <x1 x2 z>
@ -494,6 +506,9 @@ entry:
; CHECK-NEXT: Alive: <A.i B.i> ; CHECK-NEXT: Alive: <A.i B.i>
call void @capture100x32([100 x i32]* %A.i) call void @capture100x32([100 x i32]* %A.i)
; CHECK: call void @capture100x32([100 x i32]* %A.i)
; CHECK-NEXT: Alive: <A.i B.i>
call void @capture100x32([100 x i32]* %B.i) call void @capture100x32([100 x i32]* %B.i)
call void @llvm.lifetime.end.p0i8(i64 -1, i8* %0) call void @llvm.lifetime.end.p0i8(i64 -1, i8* %0)
; CHECK: call void @llvm.lifetime.end.p0i8(i64 -1, i8* %0) ; CHECK: call void @llvm.lifetime.end.p0i8(i64 -1, i8* %0)
@ -693,6 +708,8 @@ entry:
%y = alloca i8, align 4 %y = alloca i8, align 4
br i1 %a, label %if.then, label %if.else br i1 %a, label %if.then, label %if.else
; CHECK: br i1 %a, label %if.then, label %if.else
; CHECK-NEXT: Alive: <>
if.then: if.then:
; CHECK: if.then: ; CHECK: if.then:
@ -702,6 +719,8 @@ if.then:
; CHECK-NEXT: Alive: <y> ; CHECK-NEXT: Alive: <y>
br label %if.end br label %if.end
; CHECK: br label %if.end
; CHECK-NEXT: Alive: <y>
if.else: if.else:
; CHECK: if.else: ; CHECK: if.else:
@ -715,6 +734,8 @@ if.else:
; CHECK-NEXT: Alive: <x y> ; CHECK-NEXT: Alive: <x y>
br label %if.end br label %if.end
; CHECK: br label %if.end
; CHECK-NEXT: Alive: <x y>
if.end: if.end:
; CHECK: if.end: ; CHECK: if.end:
@ -724,6 +745,42 @@ if.end:
ret void ret void
} }
define void @unreachable() {
; CHECK-LABEL: define void @unreachable
entry:
; CHECK: entry:
; CHECK-NEXT: Alive: <>
%x = alloca i8, align 4
%y = alloca i8, align 4
call void @llvm.lifetime.start.p0i8(i64 4, i8* %y)
; CHECK: call void @llvm.lifetime.start.p0i8(i64 4, i8* %y)
; CHECK-NEXT: Alive: <y>
call void @llvm.lifetime.start.p0i8(i64 4, i8* %x)
; CHECK: call void @llvm.lifetime.start.p0i8(i64 4, i8* %x)
; CHECK-NEXT: Alive: <x y>
br label %end
; CHECK: br label %end
; CHECK-NEXT: Alive: <x y>
dead:
; CHECK: dead:
; CHECK-NOT: Alive:
call void @llvm.lifetime.start.p0i8(i64 4, i8* %y)
br label %end
; CHECK: br label %end
; CHECK-NOT: Alive:
end:
; CHECK: end:
; CHECK-NEXT: Alive: <x y>
ret void
}
declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
declare void @capture8(i8*) declare void @capture8(i8*)