aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Utils/CodeExtractor.cpp
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2009-08-25 00:54:39 +0000
committerOwen Anderson <resistor@mac.com>2009-08-25 00:54:39 +0000
commit9db7e91fe826ff4009d28fc82263923fa4774496 (patch)
tree6b3fe6cd1afd0bf99182f9e2c05edc40f2a5e03b /lib/Transforms/Utils/CodeExtractor.cpp
parentf6163dc85691bbccccd029c607d1d5f0b2944fd9 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79963 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Utils/CodeExtractor.cpp')
-rw-r--r--lib/Transforms/Utils/CodeExtractor.cpp22
1 files changed, 20 insertions, 2 deletions
diff --git a/lib/Transforms/Utils/CodeExtractor.cpp b/lib/Transforms/Utils/CodeExtractor.cpp
index 73458ee16e..ffd88da7bc 100644
--- a/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/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) {