forked from OSchip/llvm-project
[ScopInfo] Use statement lists for entry blocks of region statements
By using statement lists in the entry blocks of region statements, instruction level analyses also work on region statements. We currently only model the entry block of a region statements, as this is sufficient for most transformations the known-passes currently execute. Modeling instructions in the presence of control flow (e.g. infinite loops) is left out to not increase code complexity too much. It can be added when good use cases are found. This change set is reapplied, after a memory corruption issue had been fixed. llvm-svn: 312210
This commit is contained in:
parent
d3edc16416
commit
bd15d13d4e
|
|
@ -221,6 +221,14 @@ class ScopBuilder {
|
|||
/// Build the access functions for the subregion @p SR.
|
||||
void buildAccessFunctions();
|
||||
|
||||
/// Should an instruction be modeled in a ScopStmt.
|
||||
///
|
||||
/// @param Inst The instruction to check.
|
||||
/// @param L The loop in which context the instruction is looked at.
|
||||
///
|
||||
/// @returns True if the instruction should be modeled.
|
||||
bool shouldModelInst(Instruction *Inst, Loop *L);
|
||||
|
||||
/// Create ScopStmt for all BBs and non-affine subregions of @p SR.
|
||||
///
|
||||
/// @param SR A subregion of @p R.
|
||||
|
|
|
|||
|
|
@ -1198,7 +1198,15 @@ public:
|
|||
std::vector<Instruction *> Instructions, int Count);
|
||||
|
||||
/// Create an overapproximating ScopStmt for the region @p R.
|
||||
ScopStmt(Scop &parent, Region &R, Loop *SurroundingLoop);
|
||||
///
|
||||
/// @param EntryBlockInstructions The list of instructions that belong to the
|
||||
/// entry block of the region statement.
|
||||
/// Instructions are only tracked for entry
|
||||
/// blocks for now. We currently do not allow
|
||||
/// to modify the instructions of blocks later
|
||||
/// in the region statement.
|
||||
ScopStmt(Scop &parent, Region &R, Loop *SurroundingLoop,
|
||||
std::vector<Instruction *> EntryBlockInstructions);
|
||||
|
||||
/// Create a copy statement.
|
||||
///
|
||||
|
|
@ -2196,7 +2204,8 @@ private:
|
|||
///
|
||||
/// @param R The region we build the statement for.
|
||||
/// @param SurroundingLoop The loop the created statement is contained in.
|
||||
void addScopStmt(Region *R, Loop *SurroundingLoop);
|
||||
void addScopStmt(Region *R, Loop *SurroundingLoop,
|
||||
std::vector<Instruction *> EntryBlockInstructions);
|
||||
|
||||
/// Update access dimensionalities.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -659,11 +659,20 @@ void ScopBuilder::buildAccessFunctions() {
|
|||
}
|
||||
}
|
||||
|
||||
bool ScopBuilder::shouldModelInst(Instruction *Inst, Loop *L) {
|
||||
return !isa<TerminatorInst>(Inst) && !isIgnoredIntrinsic(Inst) &&
|
||||
!canSynthesize(Inst, *scop, &SE, L);
|
||||
}
|
||||
|
||||
void ScopBuilder::buildStmts(Region &SR) {
|
||||
if (scop->isNonAffineSubRegion(&SR)) {
|
||||
std::vector<Instruction *> Instructions;
|
||||
Loop *SurroundingLoop =
|
||||
getFirstNonBoxedLoopFor(SR.getEntry(), LI, scop->getBoxedLoops());
|
||||
scop->addScopStmt(&SR, SurroundingLoop);
|
||||
for (Instruction &Inst : *SR.getEntry())
|
||||
if (shouldModelInst(&Inst, SurroundingLoop))
|
||||
Instructions.push_back(&Inst);
|
||||
scop->addScopStmt(&SR, SurroundingLoop, Instructions);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -675,8 +684,7 @@ void ScopBuilder::buildStmts(Region &SR) {
|
|||
std::vector<Instruction *> Instructions;
|
||||
for (Instruction &Inst : *I->getNodeAs<BasicBlock>()) {
|
||||
Loop *L = LI.getLoopFor(Inst.getParent());
|
||||
if (!isa<TerminatorInst>(&Inst) && !isIgnoredIntrinsic(&Inst) &&
|
||||
!canSynthesize(&Inst, *scop, &SE, L))
|
||||
if (shouldModelInst(&Inst, L))
|
||||
Instructions.push_back(&Inst);
|
||||
if (Inst.getMetadata("polly_split_after")) {
|
||||
Loop *SurroundingLoop = LI.getLoopFor(I->getNodeAs<BasicBlock>());
|
||||
|
|
|
|||
|
|
@ -1676,9 +1676,11 @@ buildConditionSets(Scop &S, BasicBlock *BB, TerminatorInst *TI, Loop *L,
|
|||
ConditionSets);
|
||||
}
|
||||
|
||||
ScopStmt::ScopStmt(Scop &parent, Region &R, Loop *SurroundingLoop)
|
||||
ScopStmt::ScopStmt(Scop &parent, Region &R, Loop *SurroundingLoop,
|
||||
std::vector<Instruction *> EntryBlockInstructions)
|
||||
: Parent(parent), InvalidDomain(nullptr), Domain(nullptr), R(&R),
|
||||
Build(nullptr), SurroundingLoop(SurroundingLoop) {
|
||||
Build(nullptr), SurroundingLoop(SurroundingLoop),
|
||||
Instructions(EntryBlockInstructions) {
|
||||
BaseName = getIslCompatibleName(
|
||||
"Stmt", R.getNameStr(), parent.getNextStmtIdx(), "", UseInstructionNames);
|
||||
}
|
||||
|
|
@ -1779,7 +1781,7 @@ void ScopStmt::print(raw_ostream &OS, bool PrintInstructions) const {
|
|||
for (MemoryAccess *Access : MemAccs)
|
||||
Access->print(OS);
|
||||
|
||||
if (PrintInstructions && isBlockStmt())
|
||||
if (PrintInstructions)
|
||||
printInstructions(OS.indent(12));
|
||||
}
|
||||
|
||||
|
|
@ -3588,16 +3590,21 @@ void Scop::assumeNoOutOfBounds() {
|
|||
}
|
||||
|
||||
void Scop::removeFromStmtMap(ScopStmt &Stmt) {
|
||||
if (Stmt.isRegionStmt())
|
||||
for (Instruction *Inst : Stmt.getInstructions())
|
||||
InstStmtMap.erase(Inst);
|
||||
|
||||
if (Stmt.isRegionStmt()) {
|
||||
for (BasicBlock *BB : Stmt.getRegion()->blocks()) {
|
||||
StmtMap.erase(BB);
|
||||
// Skip entry basic block, as its instructions are already deleted as
|
||||
// part of the statement's instruction list.
|
||||
if (BB == Stmt.getEntryBlock())
|
||||
continue;
|
||||
for (Instruction &Inst : *BB)
|
||||
InstStmtMap.erase(&Inst);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
StmtMap.erase(Stmt.getBasicBlock());
|
||||
for (Instruction *Inst : Stmt.getInstructions())
|
||||
InstStmtMap.erase(Inst);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4681,12 +4688,22 @@ void Scop::addScopStmt(BasicBlock *BB, Loop *SurroundingLoop,
|
|||
}
|
||||
}
|
||||
|
||||
void Scop::addScopStmt(Region *R, Loop *SurroundingLoop) {
|
||||
void Scop::addScopStmt(Region *R, Loop *SurroundingLoop,
|
||||
std::vector<Instruction *> Instructions) {
|
||||
assert(R && "Unexpected nullptr!");
|
||||
Stmts.emplace_back(*this, *R, SurroundingLoop);
|
||||
Stmts.emplace_back(*this, *R, SurroundingLoop, Instructions);
|
||||
auto *Stmt = &Stmts.back();
|
||||
|
||||
for (Instruction *Inst : Instructions) {
|
||||
assert(!InstStmtMap.count(Inst) &&
|
||||
"Unexpected statement corresponding to the instruction.");
|
||||
InstStmtMap[Inst] = Stmt;
|
||||
}
|
||||
|
||||
for (BasicBlock *BB : R->blocks()) {
|
||||
StmtMap[BB].push_back(Stmt);
|
||||
if (BB == R->getEntry())
|
||||
continue;
|
||||
for (Instruction &Inst : *BB) {
|
||||
assert(!InstStmtMap.count(&Inst) &&
|
||||
"Unexpected statement corresponding to the instruction.");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
; RUN: opt %loadPolly -polly-scops -analyze -polly-print-instructions \
|
||||
; RUN: < %s | FileCheck %s
|
||||
|
||||
; CHECK: Statements {
|
||||
; CHECK: Stmt_bb46
|
||||
; CHECK: Domain :=
|
||||
; CHECK: [tmp44, tmp9] -> { Stmt_bb46[] : tmp9 = tmp44 };
|
||||
; CHECK: Schedule :=
|
||||
; CHECK: [tmp44, tmp9] -> { Stmt_bb46[] -> [0, 0] };
|
||||
; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
|
||||
; CHECK: [tmp44, tmp9] -> { Stmt_bb46[] -> MemRef_tmp47[] };
|
||||
; CHECK: Instructions {
|
||||
; CHECK: %tmp47 = or i64 1, %tmp14
|
||||
; CHECK: }
|
||||
; CHECK: Stmt_bb48__TO__bb56
|
||||
; CHECK: Domain :=
|
||||
; CHECK: [tmp44, tmp9] -> { Stmt_bb48__TO__bb56[i0] : tmp9 = tmp44 and 0 <= i0 < tmp44 };
|
||||
; CHECK: Schedule :=
|
||||
; CHECK: [tmp44, tmp9] -> { Stmt_bb48__TO__bb56[i0] -> [1, i0] };
|
||||
; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
|
||||
; CHECK: [tmp44, tmp9] -> { Stmt_bb48__TO__bb56[i0] -> MemRef_A[i0] };
|
||||
; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
|
||||
; CHECK: [tmp44, tmp9] -> { Stmt_bb48__TO__bb56[i0] -> MemRef_A[i0] };
|
||||
; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
|
||||
; CHECK: [tmp44, tmp9] -> { Stmt_bb48__TO__bb56[i0] -> MemRef_tmp47[] };
|
||||
; CHECK: MayWriteAccess := [Reduction Type: NONE] [Scalar: 0]
|
||||
; CHECK: [tmp44, tmp9] -> { Stmt_bb48__TO__bb56[i0] -> MemRef_A[i0] };
|
||||
; CHECK: Instructions {
|
||||
; CHECK: %tmp51 = load i64, i64* %tmp50, align 8
|
||||
; CHECK: %tmp52 = and i64 %tmp51, %tmp26
|
||||
; CHECK: %tmp53 = icmp eq i64 %tmp52, %tmp26
|
||||
; CHECK: store i64 42, i64* %tmp50, align 8
|
||||
; CHECK: }
|
||||
; CHECK: }
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
define void @quux(i32 %arg, i32 %arg1, i64* %A, i64 %tmp9, i64 %tmp24, i64 %tmp14, i64 %tmp22, i64 %tmp44) {
|
||||
bb:
|
||||
%tmp26 = or i64 %tmp22, %tmp24
|
||||
br label %bb39
|
||||
|
||||
bb39: ; preds = %bb39, %bb38
|
||||
%tmp45 = icmp eq i64 %tmp44, %tmp9
|
||||
br i1 %tmp45, label %bb46, label %bb81
|
||||
|
||||
bb46: ; preds = %bb39
|
||||
%tmp47 = or i64 1, %tmp14
|
||||
br label %bb48
|
||||
|
||||
bb48: ; preds = %bb56, %bb46
|
||||
%tmp49 = phi i64 [ 0, %bb46 ], [ %tmp57, %bb56 ]
|
||||
%tmp50 = getelementptr inbounds i64, i64* %A, i64 %tmp49
|
||||
%tmp51 = load i64, i64* %tmp50, align 8
|
||||
%tmp52 = and i64 %tmp51, %tmp26
|
||||
%tmp53 = icmp eq i64 %tmp52, %tmp26
|
||||
store i64 42, i64* %tmp50, align 8
|
||||
br i1 %tmp53, label %bb54, label %bb56
|
||||
|
||||
bb54: ; preds = %bb48
|
||||
%tmp55 = xor i64 %tmp51, %tmp47
|
||||
store i64 %tmp55, i64* %tmp50, align 8
|
||||
br label %bb56
|
||||
|
||||
bb56: ; preds = %bb54, %bb48
|
||||
%tmp57 = add nuw nsw i64 %tmp49, 1
|
||||
%tmp58 = icmp eq i64 %tmp57, %tmp9
|
||||
br i1 %tmp58, label %bb81, label %bb48
|
||||
|
||||
bb81: ; preds = %bb74, %bb56
|
||||
ret void
|
||||
}
|
||||
|
|
@ -8,6 +8,9 @@
|
|||
; CHECK-NEXT: { Stmt_Region__TO__Stmt[i0] -> [i0, 0] };
|
||||
; CHECK-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 0]
|
||||
; CHECK-NEXT: { Stmt_Region__TO__Stmt[i0] -> MemRef_C[0] };
|
||||
; CHECK-NEXT: Instructions {
|
||||
; CHECK-NEXT: %cond = fcmp oeq double 2.100000e+01, 2.100000e+01
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Stmt_Stmt
|
||||
; CHECK-NEXT: Domain :=
|
||||
; CHECK-NEXT: { Stmt_Stmt[i0] : 0 <= i0 <= 1023 };
|
||||
|
|
|
|||
Loading…
Reference in New Issue