mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-09 02:49:11 +00:00
[Polly] [BlockGen] Support partial writes in regions
Summary: The RegionGenerator traditionally kept a BlockMap that mapped from original basic blocks to newly generated basic blocks. With the introduction of partial writes such a 1:1 mapping is not possible any more, as a single basic block can be code generated into multiple basic blocks. Hence, depending on the use case we need to either use the first basic block or the last basic block. This is intended to address the last four cases of incorrect code generation in our AOSP buildbot and hopefully should turn it green. Reviewers: Meinersbur, bollu, gareevroman, efriedma, huihuiz, sebpop, simbuerg Reviewed By: Meinersbur Subscribers: pollydev, llvm-commits Tags: #polly Differential Revision: https://reviews.llvm.org/D33767 llvm-svn: 304808
This commit is contained in:
parent
eafdd862e5
commit
deefbced96
@ -795,10 +795,17 @@ public:
|
||||
__isl_keep isl_id_to_ast_expr *IdToAstExp);
|
||||
|
||||
private:
|
||||
/// A map from old to new blocks in the region.
|
||||
DenseMap<BasicBlock *, BasicBlock *> BlockMap;
|
||||
/// A map from old to the first new block in the region, that was created to
|
||||
/// model the old basic block.
|
||||
DenseMap<BasicBlock *, BasicBlock *> StartBlockMap;
|
||||
|
||||
/// The "BBMaps" for the whole region (one for each block).
|
||||
/// A map from old to the last new block in the region, that was created to
|
||||
/// model the old basic block.
|
||||
DenseMap<BasicBlock *, BasicBlock *> EndBlockMap;
|
||||
|
||||
/// The "BBMaps" for the whole region (one for each block). In case a basic
|
||||
/// block is code generated to multiple basic blocks (e.g., for partial
|
||||
/// writes), the StartBasic is used as index for the RegionMap.
|
||||
DenseMap<BasicBlock *, ValueMapT> RegionMaps;
|
||||
|
||||
/// Mapping to remember PHI nodes that still need incoming values.
|
||||
|
@ -1273,12 +1273,12 @@ BasicBlock *RegionGenerator::repairDominance(BasicBlock *BB,
|
||||
BasicBlock *BBCopy) {
|
||||
|
||||
BasicBlock *BBIDom = DT.getNode(BB)->getIDom()->getBlock();
|
||||
BasicBlock *BBCopyIDom = BlockMap.lookup(BBIDom);
|
||||
BasicBlock *BBCopyIDom = EndBlockMap.lookup(BBIDom);
|
||||
|
||||
if (BBCopyIDom)
|
||||
DT.changeImmediateDominator(BBCopy, BBCopyIDom);
|
||||
|
||||
return BBCopyIDom;
|
||||
return StartBlockMap.lookup(BBIDom);
|
||||
}
|
||||
|
||||
// This is to determine whether an llvm::Value (defined in @p BB) is usable when
|
||||
@ -1331,7 +1331,8 @@ void RegionGenerator::copyStmt(ScopStmt &Stmt, LoopToScevMapT <S,
|
||||
"Only region statements can be copied by the region generator");
|
||||
|
||||
// Forget all old mappings.
|
||||
BlockMap.clear();
|
||||
StartBlockMap.clear();
|
||||
EndBlockMap.clear();
|
||||
RegionMaps.clear();
|
||||
IncompletePHINodeMap.clear();
|
||||
|
||||
@ -1353,8 +1354,10 @@ void RegionGenerator::copyStmt(ScopStmt &Stmt, LoopToScevMapT <S,
|
||||
generateScalarLoads(Stmt, LTS, EntryBBMap, IdToAstExp);
|
||||
|
||||
for (auto PI = pred_begin(EntryBB), PE = pred_end(EntryBB); PI != PE; ++PI)
|
||||
if (!R->contains(*PI))
|
||||
BlockMap[*PI] = EntryBBCopy;
|
||||
if (!R->contains(*PI)) {
|
||||
StartBlockMap[*PI] = EntryBBCopy;
|
||||
EndBlockMap[*PI] = EntryBBCopy;
|
||||
}
|
||||
|
||||
// Iterate over all blocks in the region in a breadth-first search.
|
||||
std::deque<BasicBlock *> Blocks;
|
||||
@ -1388,7 +1391,8 @@ void RegionGenerator::copyStmt(ScopStmt &Stmt, LoopToScevMapT <S,
|
||||
copyBB(Stmt, BB, BBCopy, RegionMap, LTS, IdToAstExp);
|
||||
|
||||
// In order to remap PHI nodes we store also basic block mappings.
|
||||
BlockMap[BB] = BBCopy;
|
||||
StartBlockMap[BB] = BBCopy;
|
||||
EndBlockMap[BB] = Builder.GetInsertBlock();
|
||||
|
||||
// Add values to incomplete PHI nodes waiting for this block to be copied.
|
||||
for (const PHINodePairTy &PHINodePair : IncompletePHINodeMap[BB])
|
||||
@ -1409,9 +1413,10 @@ void RegionGenerator::copyStmt(ScopStmt &Stmt, LoopToScevMapT <S,
|
||||
BasicBlock *ExitBBCopy = SplitBlock(Builder.GetInsertBlock(),
|
||||
&*Builder.GetInsertPoint(), &DT, &LI);
|
||||
ExitBBCopy->setName("polly.stmt." + R->getExit()->getName() + ".exit");
|
||||
BlockMap[R->getExit()] = ExitBBCopy;
|
||||
StartBlockMap[R->getExit()] = ExitBBCopy;
|
||||
EndBlockMap[R->getExit()] = ExitBBCopy;
|
||||
|
||||
BasicBlock *ExitDomBBCopy = BlockMap.lookup(findExitDominator(DT, R));
|
||||
BasicBlock *ExitDomBBCopy = EndBlockMap.lookup(findExitDominator(DT, R));
|
||||
assert(ExitDomBBCopy &&
|
||||
"Common exit dominator must be within region; at least the entry node "
|
||||
"must match");
|
||||
@ -1421,19 +1426,20 @@ void RegionGenerator::copyStmt(ScopStmt &Stmt, LoopToScevMapT <S,
|
||||
// region control flow by hand after all blocks have been copied.
|
||||
for (BasicBlock *BB : SeenBlocks) {
|
||||
|
||||
BasicBlock *BBCopy = BlockMap[BB];
|
||||
BasicBlock *BBCopyStart = StartBlockMap[BB];
|
||||
BasicBlock *BBCopyEnd = EndBlockMap[BB];
|
||||
TerminatorInst *TI = BB->getTerminator();
|
||||
if (isa<UnreachableInst>(TI)) {
|
||||
while (!BBCopy->empty())
|
||||
BBCopy->begin()->eraseFromParent();
|
||||
new UnreachableInst(BBCopy->getContext(), BBCopy);
|
||||
while (!BBCopyEnd->empty())
|
||||
BBCopyEnd->begin()->eraseFromParent();
|
||||
new UnreachableInst(BBCopyEnd->getContext(), BBCopyEnd);
|
||||
continue;
|
||||
}
|
||||
|
||||
Instruction *BICopy = BBCopy->getTerminator();
|
||||
Instruction *BICopy = BBCopyEnd->getTerminator();
|
||||
|
||||
ValueMapT &RegionMap = RegionMaps[BBCopy];
|
||||
RegionMap.insert(BlockMap.begin(), BlockMap.end());
|
||||
ValueMapT &RegionMap = RegionMaps[BBCopyStart];
|
||||
RegionMap.insert(StartBlockMap.begin(), StartBlockMap.end());
|
||||
|
||||
Builder.SetInsertPoint(BICopy);
|
||||
copyInstScalar(Stmt, TI, RegionMap, LTS);
|
||||
@ -1447,7 +1453,7 @@ void RegionGenerator::copyStmt(ScopStmt &Stmt, LoopToScevMapT <S,
|
||||
if (L == nullptr || L->getHeader() != BB || !R->contains(L))
|
||||
continue;
|
||||
|
||||
BasicBlock *BBCopy = BlockMap[BB];
|
||||
BasicBlock *BBCopy = StartBlockMap[BB];
|
||||
Value *NullVal = Builder.getInt32(0);
|
||||
PHINode *LoopPHI =
|
||||
PHINode::Create(Builder.getInt32Ty(), 2, "polly.subregion.iv");
|
||||
@ -1460,9 +1466,9 @@ void RegionGenerator::copyStmt(ScopStmt &Stmt, LoopToScevMapT <S,
|
||||
if (!R->contains(PredBB))
|
||||
continue;
|
||||
if (L->contains(PredBB))
|
||||
LoopPHI->addIncoming(LoopPHIInc, BlockMap[PredBB]);
|
||||
LoopPHI->addIncoming(LoopPHIInc, EndBlockMap[PredBB]);
|
||||
else
|
||||
LoopPHI->addIncoming(NullVal, BlockMap[PredBB]);
|
||||
LoopPHI->addIncoming(NullVal, EndBlockMap[PredBB]);
|
||||
}
|
||||
|
||||
for (auto *PredBBCopy : make_range(pred_begin(BBCopy), pred_end(BBCopy)))
|
||||
@ -1477,7 +1483,8 @@ void RegionGenerator::copyStmt(ScopStmt &Stmt, LoopToScevMapT <S,
|
||||
|
||||
// Write values visible to other statements.
|
||||
generateScalarStores(Stmt, LTS, ValueMap, IdToAstExp);
|
||||
BlockMap.clear();
|
||||
StartBlockMap.clear();
|
||||
EndBlockMap.clear();
|
||||
RegionMaps.clear();
|
||||
IncompletePHINodeMap.clear();
|
||||
}
|
||||
@ -1497,7 +1504,7 @@ PHINode *RegionGenerator::buildExitPHI(MemoryAccess *MA, LoopToScevMapT <S,
|
||||
if (OrigPHI->getParent() != SubR->getExit()) {
|
||||
BasicBlock *FormerExit = SubR->getExitingBlock();
|
||||
if (FormerExit)
|
||||
NewSubregionExit = BlockMap.lookup(FormerExit);
|
||||
NewSubregionExit = StartBlockMap.lookup(FormerExit);
|
||||
}
|
||||
|
||||
PHINode *NewPHI = PHINode::Create(OrigPHI->getType(), Incoming.size(),
|
||||
@ -1507,15 +1514,17 @@ PHINode *RegionGenerator::buildExitPHI(MemoryAccess *MA, LoopToScevMapT <S,
|
||||
// Add the incoming values to the PHI.
|
||||
for (auto &Pair : Incoming) {
|
||||
BasicBlock *OrigIncomingBlock = Pair.first;
|
||||
BasicBlock *NewIncomingBlock = BlockMap.lookup(OrigIncomingBlock);
|
||||
Builder.SetInsertPoint(NewIncomingBlock->getTerminator());
|
||||
assert(RegionMaps.count(NewIncomingBlock));
|
||||
ValueMapT *LocalBBMap = &RegionMaps[NewIncomingBlock];
|
||||
BasicBlock *NewIncomingBlockStart = StartBlockMap.lookup(OrigIncomingBlock);
|
||||
BasicBlock *NewIncomingBlockEnd = EndBlockMap.lookup(OrigIncomingBlock);
|
||||
Builder.SetInsertPoint(NewIncomingBlockEnd->getTerminator());
|
||||
assert(RegionMaps.count(NewIncomingBlockStart));
|
||||
assert(RegionMaps.count(NewIncomingBlockEnd));
|
||||
ValueMapT *LocalBBMap = &RegionMaps[NewIncomingBlockStart];
|
||||
|
||||
Value *OrigIncomingValue = Pair.second;
|
||||
Value *NewIncomingValue =
|
||||
getNewValue(*Stmt, OrigIncomingValue, *LocalBBMap, LTS, L);
|
||||
NewPHI->addIncoming(NewIncomingValue, NewIncomingBlock);
|
||||
NewPHI->addIncoming(NewIncomingValue, NewIncomingBlockEnd);
|
||||
}
|
||||
|
||||
return NewPHI;
|
||||
@ -1584,16 +1593,19 @@ void RegionGenerator::addOperandToPHI(ScopStmt &Stmt, PHINode *PHI,
|
||||
LoopToScevMapT <S) {
|
||||
// If the incoming block was not yet copied mark this PHI as incomplete.
|
||||
// Once the block will be copied the incoming value will be added.
|
||||
BasicBlock *BBCopy = BlockMap[IncomingBB];
|
||||
if (!BBCopy) {
|
||||
BasicBlock *BBCopyStart = StartBlockMap[IncomingBB];
|
||||
BasicBlock *BBCopyEnd = EndBlockMap[IncomingBB];
|
||||
if (!BBCopyStart) {
|
||||
assert(!BBCopyEnd);
|
||||
assert(Stmt.contains(IncomingBB) &&
|
||||
"Bad incoming block for PHI in non-affine region");
|
||||
IncompletePHINodeMap[IncomingBB].push_back(std::make_pair(PHI, PHICopy));
|
||||
return;
|
||||
}
|
||||
|
||||
assert(RegionMaps.count(BBCopy) && "Incoming PHI block did not have a BBMap");
|
||||
ValueMapT &BBCopyMap = RegionMaps[BBCopy];
|
||||
assert(RegionMaps.count(BBCopyStart) &&
|
||||
"Incoming PHI block did not have a BBMap");
|
||||
ValueMapT &BBCopyMap = RegionMaps[BBCopyStart];
|
||||
|
||||
Value *OpCopy = nullptr;
|
||||
|
||||
@ -1603,17 +1615,17 @@ void RegionGenerator::addOperandToPHI(ScopStmt &Stmt, PHINode *PHI,
|
||||
// If the current insert block is different from the PHIs incoming block
|
||||
// change it, otherwise do not.
|
||||
auto IP = Builder.GetInsertPoint();
|
||||
if (IP->getParent() != BBCopy)
|
||||
Builder.SetInsertPoint(BBCopy->getTerminator());
|
||||
if (IP->getParent() != BBCopyEnd)
|
||||
Builder.SetInsertPoint(BBCopyEnd->getTerminator());
|
||||
OpCopy = getNewValue(Stmt, Op, BBCopyMap, LTS, getLoopForStmt(Stmt));
|
||||
if (IP->getParent() != BBCopy)
|
||||
if (IP->getParent() != BBCopyEnd)
|
||||
Builder.SetInsertPoint(&*IP);
|
||||
} else {
|
||||
// All edges from outside the non-affine region become a single edge
|
||||
// in the new copy of the non-affine region. Make sure to only add the
|
||||
// corresponding edge the first time we encounter a basic block from
|
||||
// outside the non-affine region.
|
||||
if (PHICopy->getBasicBlockIndex(BBCopy) >= 0)
|
||||
if (PHICopy->getBasicBlockIndex(BBCopyEnd) >= 0)
|
||||
return;
|
||||
|
||||
// Get the reloaded value.
|
||||
@ -1621,8 +1633,7 @@ void RegionGenerator::addOperandToPHI(ScopStmt &Stmt, PHINode *PHI,
|
||||
}
|
||||
|
||||
assert(OpCopy && "Incoming PHI value was not copied properly");
|
||||
assert(BBCopy && "Incoming PHI block was not copied properly");
|
||||
PHICopy->addIncoming(OpCopy, BBCopy);
|
||||
PHICopy->addIncoming(OpCopy, BBCopyEnd);
|
||||
}
|
||||
|
||||
void RegionGenerator::copyPHIInstruction(ScopStmt &Stmt, PHINode *PHI,
|
||||
|
68
polly/test/Isl/CodeGen/partial_write_in_region.ll
Normal file
68
polly/test/Isl/CodeGen/partial_write_in_region.ll
Normal file
@ -0,0 +1,68 @@
|
||||
; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S \
|
||||
; RUN: -polly-import-jscop-postfix=transformed -polly-codegen \
|
||||
; RUN: -verify-dom-info \
|
||||
; RUN: -S < %s | FileCheck %s
|
||||
;
|
||||
; void foo(long A[], float B[], float C[]) {
|
||||
; for (long i = 0; i < 1024; i++) {
|
||||
; if (A[i]) {
|
||||
; S: B[i]++;
|
||||
; T: C[42] = 1;
|
||||
; }
|
||||
; }
|
||||
; }
|
||||
|
||||
; CHECK: polly.stmt.bb5: ; preds = %polly.stmt.bb2
|
||||
; CHECK-NEXT: %scevgep10 = getelementptr float, float* %B, i64 %polly.indvar
|
||||
; CHECK-NEXT: %tmp7_p_scalar_ = load float, float* %scevgep10
|
||||
; CHECK-NEXT: %p_tmp8 = fadd float %tmp7_p_scalar_, 1.000000e+00
|
||||
; CHECK-NEXT: %24 = icmp sle i64 %polly.indvar, 9
|
||||
; CHECK-NEXT: %polly.Stmt_bb2__TO__bb9_MayWrite2.cond = icmp ne i1 %24, false
|
||||
; CHECK-NEXT: br i1 %polly.Stmt_bb2__TO__bb9_MayWrite2.cond, label %polly.stmt.bb5.Stmt_bb2__TO__bb9_MayWrite2.partial, label %polly.stmt.bb5.cont
|
||||
|
||||
; CHECK: polly.stmt.bb5.Stmt_bb2__TO__bb9_MayWrite2.partial: ; preds = %polly.stmt.bb5
|
||||
; CHECK-NEXT: %polly.access.B11 = getelementptr float, float* %B, i64 %polly.indvar
|
||||
; CHECK-NEXT: store float %p_tmp8, float* %polly.access.B11
|
||||
; CHECK-NEXT: br label %polly.stmt.bb5.cont
|
||||
|
||||
; CHECK: polly.stmt.bb5.cont: ; preds = %polly.stmt.bb5, %polly.stmt.bb5.Stmt_bb2__TO__bb9_MayWrite2.partial
|
||||
; CHECK-NEXT: br label %polly.stmt.bb9b
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
define void @partial_write_in_region(i64* %A, float* %B, float* %C) {
|
||||
bb:
|
||||
br label %bb1
|
||||
|
||||
bb1: ; preds = %bb10, %bb
|
||||
%i.0 = phi i64 [ 0, %bb ], [ %tmp11, %bb10 ]
|
||||
%exitcond = icmp ne i64 %i.0, 1024
|
||||
br i1 %exitcond, label %bb2, label %bb12
|
||||
|
||||
bb2: ; preds = %bb1
|
||||
%tmp = getelementptr inbounds i64, i64* %A, i64 %i.0
|
||||
%tmp3 = load i64, i64* %tmp, align 8
|
||||
%tmp4 = icmp eq i64 %tmp3, 0
|
||||
br i1 %tmp4, label %bb9, label %bb5
|
||||
|
||||
bb5: ; preds = %bb2
|
||||
%tmp6 = getelementptr inbounds float, float* %B, i64 %i.0
|
||||
%tmp7 = load float, float* %tmp6, align 4
|
||||
%tmp8 = fadd float %tmp7, 1.000000e+00
|
||||
store float %tmp8, float* %tmp6, align 4
|
||||
br label %bb9b
|
||||
|
||||
bb9b:
|
||||
store float 42.0, float* %C
|
||||
br label %bb9
|
||||
|
||||
bb9: ; preds = %bb2, %bb5
|
||||
br label %bb10
|
||||
|
||||
bb10: ; preds = %bb9
|
||||
%tmp11 = add nuw nsw i64 %i.0, 1
|
||||
br label %bb1
|
||||
|
||||
bb12: ; preds = %bb1
|
||||
ret void
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
{
|
||||
"arrays" : [
|
||||
{
|
||||
"name" : "MemRef_A",
|
||||
"sizes" : [ "*" ],
|
||||
"type" : "i64"
|
||||
},
|
||||
{
|
||||
"name" : "MemRef_B",
|
||||
"sizes" : [ "*" ],
|
||||
"type" : "float"
|
||||
},
|
||||
{
|
||||
"name" : "MemRef_C",
|
||||
"sizes" : [ "*" ],
|
||||
"type" : "float"
|
||||
}
|
||||
],
|
||||
"context" : "{ : }",
|
||||
"name" : "%bb1---%bb12",
|
||||
"statements" : [
|
||||
{
|
||||
"accesses" : [
|
||||
{
|
||||
"kind" : "read",
|
||||
"relation" : "{ Stmt_bb2__TO__bb9[i0] -> MemRef_A[i0] }"
|
||||
},
|
||||
{
|
||||
"kind" : "read",
|
||||
"relation" : "{ Stmt_bb2__TO__bb9[i0] -> MemRef_B[i0] }"
|
||||
},
|
||||
{
|
||||
"kind" : "write",
|
||||
"relation" : "{ Stmt_bb2__TO__bb9[i0] -> MemRef_B[i0] }"
|
||||
},
|
||||
{
|
||||
"kind" : "write",
|
||||
"relation" : "{ Stmt_bb2__TO__bb9[i0] -> MemRef_C[0] }"
|
||||
}
|
||||
],
|
||||
"domain" : "{ Stmt_bb2__TO__bb9[i0] : 0 <= i0 <= 1023 }",
|
||||
"name" : "Stmt_bb2__TO__bb9",
|
||||
"schedule" : "{ Stmt_bb2__TO__bb9[i0] -> [i0] }"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
{
|
||||
"arrays" : [
|
||||
{
|
||||
"name" : "MemRef_A",
|
||||
"sizes" : [ "*" ],
|
||||
"type" : "i64"
|
||||
},
|
||||
{
|
||||
"name" : "MemRef_B",
|
||||
"sizes" : [ "*" ],
|
||||
"type" : "float"
|
||||
},
|
||||
{
|
||||
"name" : "MemRef_C",
|
||||
"sizes" : [ "*" ],
|
||||
"type" : "float"
|
||||
}
|
||||
],
|
||||
"context" : "{ : }",
|
||||
"name" : "%bb1---%bb12",
|
||||
"statements" : [
|
||||
{
|
||||
"accesses" : [
|
||||
{
|
||||
"kind" : "read",
|
||||
"relation" : "{ Stmt_bb2__TO__bb9[i0] -> MemRef_A[i0] }"
|
||||
},
|
||||
{
|
||||
"kind" : "read",
|
||||
"relation" : "{ Stmt_bb2__TO__bb9[i0] -> MemRef_B[i0] }"
|
||||
},
|
||||
{
|
||||
"kind" : "write",
|
||||
"relation" : "{ Stmt_bb2__TO__bb9[i0] -> MemRef_B[i0] : i0 < 10}"
|
||||
},
|
||||
{
|
||||
"kind" : "write",
|
||||
"relation" : "{ Stmt_bb2__TO__bb9[i0] -> MemRef_C[0] }"
|
||||
}
|
||||
],
|
||||
"domain" : "{ Stmt_bb2__TO__bb9[i0] : 0 <= i0 <= 1023 }",
|
||||
"name" : "Stmt_bb2__TO__bb9",
|
||||
"schedule" : "{ Stmt_bb2__TO__bb9[i0] -> [i0] }"
|
||||
}
|
||||
]
|
||||
}
|
80
polly/test/Isl/CodeGen/partial_write_in_region_with_loop.ll
Normal file
80
polly/test/Isl/CodeGen/partial_write_in_region_with_loop.ll
Normal file
@ -0,0 +1,80 @@
|
||||
; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S \
|
||||
; RUN: -polly-import-jscop-postfix=transformed -polly-codegen \
|
||||
; RUN: -verify-dom-info -polly-allow-nonaffine-loops \
|
||||
; RUN: -S < %s | FileCheck %s
|
||||
|
||||
; This test verifies that partial writes within non-affine loops are code
|
||||
; generated correctly.
|
||||
|
||||
; CHECK:polly.stmt.bb3:
|
||||
; CHECK-NEXT: %polly.subregion.iv = phi i32 [ %polly.subregion.iv.inc, %polly.stmt.bb5.cont ], [ 0, %polly.stmt.bb3.entry ]
|
||||
; CHECK-NEXT: %polly.j.0 = phi i64 [ %j.0.phiops.reload, %polly.stmt.bb3.entry ], [ %p_tmp10, %polly.stmt.bb5.cont ]
|
||||
; CHECK-NEXT: %p_tmp = mul nsw i64 %polly.indvar, %polly.indvar
|
||||
; CHECK-NEXT: %p_tmp4 = icmp slt i64 %polly.j.0, %p_tmp
|
||||
; CHECK-NEXT: %polly.subregion.iv.inc = add i32 %polly.subregion.iv, 1
|
||||
; CHECK-NEXT: br i1 %p_tmp4, label %polly.stmt.bb5, label %polly.stmt.bb11.exit
|
||||
|
||||
; CHECK:polly.stmt.bb5:
|
||||
; CHECK-NEXT: %p_tmp6 = getelementptr inbounds float, float* %B, i64 42
|
||||
; CHECK-NEXT: %tmp7_p_scalar_ = load float, float* %p_tmp6
|
||||
; CHECK-NEXT: %p_tmp8 = fadd float %tmp7_p_scalar_, 1.000000e+00
|
||||
; CHECK-NEXT: %8 = icmp sle i64 %polly.indvar, 9
|
||||
; CHECK-NEXT: %polly.Stmt_bb3__TO__bb11_MayWrite2.cond = icmp ne i1 %8, false
|
||||
; CHECK-NEXT: br i1 %polly.Stmt_bb3__TO__bb11_MayWrite2.cond, label %polly.stmt.bb5.Stmt_bb3__TO__bb11_MayWrite2.partial, label %polly.stmt.bb5.cont
|
||||
|
||||
; CHECK:polly.stmt.bb5.Stmt_bb3__TO__bb11_MayWrite2.partial: ; preds = %polly.stmt.bb5
|
||||
; CHECK-NEXT: %polly.access.B3 = getelementptr float, float* %B, i64 42
|
||||
; CHECK-NEXT: store float %p_tmp8, float* %polly.access.B3
|
||||
; CHECK-NEXT: br label %polly.stmt.bb5.cont
|
||||
|
||||
; CHECK:polly.stmt.bb5.cont:
|
||||
; CHECK-NEXT: %p_tmp10 = add nuw nsw i64 %polly.j.0, 1
|
||||
; CHECK-NEXT: br label %polly.stmt.bb3
|
||||
|
||||
|
||||
|
||||
; void foo(long A[], float B[], long *x) {
|
||||
; for (long i = 0; i < 1024; i++)
|
||||
; for (long j = *x; j < i * i; j++)
|
||||
; B[42]++;
|
||||
; }
|
||||
;
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
define void @partial_write_in_region_with_loop(i64* %A, float* %B, i64* %xptr) {
|
||||
bb:
|
||||
br label %bb1
|
||||
|
||||
bb1: ; preds = %bb12, %bb
|
||||
%i.0 = phi i64 [ 0, %bb ], [ %tmp13, %bb12 ]
|
||||
%exitcond = icmp ne i64 %i.0, 1024
|
||||
br i1 %exitcond, label %bb2, label %bb14
|
||||
|
||||
bb2: ; preds = %bb1
|
||||
%x = load i64, i64* %xptr
|
||||
br label %bb3
|
||||
|
||||
bb3: ; preds = %bb9, %bb2
|
||||
%j.0 = phi i64 [ %x, %bb2 ], [ %tmp10, %bb5 ]
|
||||
%tmp = mul nsw i64 %i.0, %i.0
|
||||
%tmp4 = icmp slt i64 %j.0, %tmp
|
||||
br i1 %tmp4, label %bb5, label %bb11
|
||||
|
||||
bb5: ; preds = %bb3
|
||||
%tmp6 = getelementptr inbounds float, float* %B, i64 42
|
||||
%tmp7 = load float, float* %tmp6, align 4
|
||||
%tmp8 = fadd float %tmp7, 1.000000e+00
|
||||
store float %tmp8, float* %tmp6, align 4
|
||||
%tmp10 = add nuw nsw i64 %j.0, 1
|
||||
br label %bb3
|
||||
|
||||
bb11: ; preds = %bb3
|
||||
br label %bb12
|
||||
|
||||
bb12: ; preds = %bb11
|
||||
%tmp13 = add nuw nsw i64 %i.0, 1
|
||||
br label %bb1
|
||||
|
||||
bb14: ; preds = %bb1
|
||||
ret void
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
{
|
||||
"arrays" : [
|
||||
{
|
||||
"name" : "MemRef_xptr",
|
||||
"sizes" : [ "*" ],
|
||||
"type" : "i64"
|
||||
},
|
||||
{
|
||||
"name" : "MemRef_B",
|
||||
"sizes" : [ "*" ],
|
||||
"type" : "float"
|
||||
}
|
||||
],
|
||||
"context" : "{ : }",
|
||||
"name" : "%bb1---%bb14",
|
||||
"statements" : [
|
||||
{
|
||||
"accesses" : [
|
||||
{
|
||||
"kind" : "read",
|
||||
"relation" : "{ Stmt_bb2[i0] -> MemRef_xptr[0] }"
|
||||
},
|
||||
{
|
||||
"kind" : "write",
|
||||
"relation" : "{ Stmt_bb2[i0] -> MemRef_j_0__phi[] }"
|
||||
}
|
||||
],
|
||||
"domain" : "{ Stmt_bb2[i0] : 0 <= i0 <= 1023 }",
|
||||
"name" : "Stmt_bb2",
|
||||
"schedule" : "{ Stmt_bb2[i0] -> [i0, 0] }"
|
||||
},
|
||||
{
|
||||
"accesses" : [
|
||||
{
|
||||
"kind" : "read",
|
||||
"relation" : "{ Stmt_bb3__TO__bb11[i0] -> MemRef_j_0__phi[] }"
|
||||
},
|
||||
{
|
||||
"kind" : "read",
|
||||
"relation" : "{ Stmt_bb3__TO__bb11[i0] -> MemRef_B[42] }"
|
||||
},
|
||||
{
|
||||
"kind" : "write",
|
||||
"relation" : "{ Stmt_bb3__TO__bb11[i0] -> MemRef_B[42] }"
|
||||
}
|
||||
],
|
||||
"domain" : "{ Stmt_bb3__TO__bb11[i0] : 0 <= i0 <= 1023 }",
|
||||
"name" : "Stmt_bb3__TO__bb11",
|
||||
"schedule" : "{ Stmt_bb3__TO__bb11[i0] -> [i0, 1] }"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
{
|
||||
"arrays" : [
|
||||
{
|
||||
"name" : "MemRef_xptr",
|
||||
"sizes" : [ "*" ],
|
||||
"type" : "i64"
|
||||
},
|
||||
{
|
||||
"name" : "MemRef_B",
|
||||
"sizes" : [ "*" ],
|
||||
"type" : "float"
|
||||
}
|
||||
],
|
||||
"context" : "{ : }",
|
||||
"name" : "%bb1---%bb14",
|
||||
"statements" : [
|
||||
{
|
||||
"accesses" : [
|
||||
{
|
||||
"kind" : "read",
|
||||
"relation" : "{ Stmt_bb2[i0] -> MemRef_xptr[0] }"
|
||||
},
|
||||
{
|
||||
"kind" : "write",
|
||||
"relation" : "{ Stmt_bb2[i0] -> MemRef_j_0__phi[] }"
|
||||
}
|
||||
],
|
||||
"domain" : "{ Stmt_bb2[i0] : 0 <= i0 <= 1023 }",
|
||||
"name" : "Stmt_bb2",
|
||||
"schedule" : "{ Stmt_bb2[i0] -> [i0, 0] }"
|
||||
},
|
||||
{
|
||||
"accesses" : [
|
||||
{
|
||||
"kind" : "read",
|
||||
"relation" : "{ Stmt_bb3__TO__bb11[i0] -> MemRef_j_0__phi[] }"
|
||||
},
|
||||
{
|
||||
"kind" : "read",
|
||||
"relation" : "{ Stmt_bb3__TO__bb11[i0] -> MemRef_B[42] }"
|
||||
},
|
||||
{
|
||||
"kind" : "write",
|
||||
"relation" : "{ Stmt_bb3__TO__bb11[i0] -> MemRef_B[42] : i0 < 10 }"
|
||||
}
|
||||
],
|
||||
"domain" : "{ Stmt_bb3__TO__bb11[i0] : 0 <= i0 <= 1023 }",
|
||||
"name" : "Stmt_bb3__TO__bb11",
|
||||
"schedule" : "{ Stmt_bb3__TO__bb11[i0] -> [i0, 1] }"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user