Skip to content

Commit b2978b2

Browse files
committed
[Tapir] Handle structure-return parameters correctly in outlined helper functions. This commit addresses issue #38.
1 parent 0b05cc6 commit b2978b2

File tree

3 files changed

+1009
-6
lines changed

3 files changed

+1009
-6
lines changed

llvm/lib/Transforms/Tapir/LoopSpawning.cpp

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -672,12 +672,17 @@ void DACLoopSpawning::implementDACIterSpawnOnHelper(
672672
IRBuilder<> Builder(&(RecurDet->front()));
673673
SetVector<Value*> RecurInputs;
674674
Function::arg_iterator AI = Helper->arg_begin();
675+
// Handle an initial sret argument, if necessary. Based on how
676+
// the Helper function is created, any sret parameter will be the
677+
// first parameter.
678+
if (Helper->hasParamAttribute(0, Attribute::StructRet))
679+
RecurInputs.insert(&*AI++);
675680
assert(cast<Argument>(CanonicalIVInput) == &*AI &&
676-
"First argument does not match original input to canonical IV.");
681+
"First non-sret argument does not match original input to canonical IV.");
677682
RecurInputs.insert(CanonicalIVStart);
678683
++AI;
679684
assert(Limit == &*AI &&
680-
"Second argument does not match original input to the loop limit.");
685+
"Second non-sret argument does not match original input to the loop limit.");
681686
RecurInputs.insert(MidIter);
682687
++AI;
683688
for (Function::arg_iterator AE = Helper->arg_end(); AI != AE; ++AI)
@@ -1103,6 +1108,7 @@ bool DACLoopSpawning::processLoop() {
11031108
SetVector<Value *> BodyInputs, BodyOutputs;
11041109
ValueToValueMapTy VMap, InputMap;
11051110
std::vector<BasicBlock *> LoopBlocks;
1111+
Value *SRetInput = nullptr;
11061112

11071113
// Get the sync region containing this Tapir loop.
11081114
const Instruction *InputSyncRegion;
@@ -1134,6 +1140,23 @@ bool DACLoopSpawning::processLoop() {
11341140
findInputsOutputs(Blocks, BodyInputs, BodyOutputs, &HandledExits, DT);
11351141
}
11361142

1143+
// Scan for any sret parameters in BodyInputs and add them first.
1144+
if (F->hasStructRetAttr()) {
1145+
Function::arg_iterator ArgIter = F->arg_begin();
1146+
if (F->hasParamAttribute(0, Attribute::StructRet))
1147+
if (BodyInputs.count(&*ArgIter))
1148+
SRetInput = &*ArgIter;
1149+
if (F->hasParamAttribute(1, Attribute::StructRet)) {
1150+
++ArgIter;
1151+
if (BodyInputs.count(&*ArgIter))
1152+
SRetInput = &*ArgIter;
1153+
}
1154+
}
1155+
if (SRetInput) {
1156+
DEBUG(dbgs() << "sret input " << *SRetInput << "\n");
1157+
Inputs.insert(SRetInput);
1158+
}
1159+
11371160
// Add argument for start of CanonicalIV.
11381161
DEBUG({
11391162
Value *CanonicalIVInput =
@@ -1407,6 +1430,9 @@ bool DACLoopSpawning::processLoop() {
14071430
{
14081431
// Setup arguments for call.
14091432
SmallVector<Value *, 4> TopCallArgs;
1433+
// Add sret input, if it exists.
1434+
if (SRetInput)
1435+
TopCallArgs.push_back(SRetInput);
14101436
// Add start iteration 0.
14111437
assert(CanonicalSCEV->getStart()->isZero() &&
14121438
"Canonical IV does not start at zero.");

llvm/lib/Transforms/Tapir/TapirUtils.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,30 @@ Function *llvm::extractDetachBodyToFunction(
339339

340340
// Fix up the inputs.
341341
SetVector<Value *> Inputs;
342-
for (Value *V : BodyInputs) {
343-
if (V == SyncRegion) continue;
344-
if (!Inputs.count(V))
345-
Inputs.insert(V);
342+
{
343+
// Scan for any sret parameters in BodyInputs and add them first.
344+
Value *SRetInput = nullptr;
345+
if (F.hasStructRetAttr()) {
346+
Function::arg_iterator ArgIter = F.arg_begin();
347+
if (F.hasParamAttribute(0, Attribute::StructRet))
348+
if (BodyInputs.count(&*ArgIter))
349+
SRetInput = &*ArgIter;
350+
if (F.hasParamAttribute(1, Attribute::StructRet)) {
351+
++ArgIter;
352+
if (BodyInputs.count(&*ArgIter))
353+
SRetInput = &*ArgIter;
354+
}
355+
}
356+
if (SRetInput) {
357+
DEBUG(dbgs() << "sret input " << *SRetInput << "\n");
358+
Inputs.insert(SRetInput);
359+
}
360+
// Add the remaining inputs.
361+
for (Value *V : BodyInputs) {
362+
if (V == SyncRegion) continue;
363+
if (!Inputs.count(V))
364+
Inputs.insert(V);
365+
}
346366
}
347367

348368
// Clone the detached CFG into a helper function.

0 commit comments

Comments
 (0)