diff options
author | Owen Anderson <resistor@mac.com> | 2009-08-25 00:54:39 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2009-08-25 00:54:39 +0000 |
commit | 34e6148dc8f39fa74e89694f3a2ae4e399330c0a (patch) | |
tree | af1726dc172b59f2a6fcca705f4a64f4ac545825 /llvm/lib/Transforms/Utils/CodeExtractor.cpp | |
parent | 9d01b5b40cd7d451b8e58f12f5df78b3ff11e651 (diff) | |
download | bcm5719-llvm-34e6148dc8f39fa74e89694f3a2ae4e399330c0a.tar.gz bcm5719-llvm-34e6148dc8f39fa74e89694f3a2ae4e399330c0a.zip |
Handle a corner case when extracing code regions where one of the immediate successor
of an extracted block contains a PHI using a value defined in the extracted region.
With this patch, the partial inliner now passes MultiSource/Applications.
llvm-svn: 79963
Diffstat (limited to 'llvm/lib/Transforms/Utils/CodeExtractor.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/CodeExtractor.cpp | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp index 73458ee16e7..ffd88da7bc8 100644 --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -369,7 +369,7 @@ emitCallAndSwitchStatement(Function *newFunction, BasicBlock *codeReplacer, Values &inputs, Values &outputs) { // Emit a call to the new function, passing in: *pointer to struct (if // aggregating parameters), or plan inputs and allocated memory for outputs - std::vector<Value*> params, StructValues, ReloadOutputs; + std::vector<Value*> params, StructValues, ReloadOutputs, Reloads; LLVMContext &Context = newFunction->getContext(); @@ -446,6 +446,7 @@ emitCallAndSwitchStatement(Function *newFunction, BasicBlock *codeReplacer, Output = ReloadOutputs[i]; } LoadInst *load = new LoadInst(Output, outputs[i]->getName()+".reload"); + Reloads.push_back(load); codeReplacer->getInstList().push_back(load); std::vector<User*> Users(outputs[i]->use_begin(), outputs[i]->use_end()); for (unsigned u = 0, e = Users.size(); u != e; ++u) { @@ -532,8 +533,25 @@ emitCallAndSwitchStatement(Function *newFunction, BasicBlock *codeReplacer, DominatesDef = false; } - if (DT) + if (DT) { DominatesDef = DT->dominates(DefBlock, OldTarget); + + // If the output value is used by a phi in the target block, + // then we need to test for dominance of the phi's predecessor + // instead. Unfortunately, this a little complicated since we + // have already rewritten uses of the value to uses of the reload. + for (Value::use_iterator UI = Reloads[out]->use_begin(), + UE = Reloads[out]->use_end(); UI != UE; ++UI) { + PHINode *P = dyn_cast<PHINode>(*UI); + if (!P || P->getParent() != OldTarget) continue; + + BasicBlock* pred = P->getIncomingBlock(UI); + if (DT->dominates(DefBlock, pred)) { + DominatesDef = true; + break; + } + } + } if (DominatesDef) { if (AggregateArgs) { |