Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some bugs with task-simplify and function inlining #285

Merged
merged 6 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions clang/test/Cilk/hyper-destruct2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ struct Outer {
};

// Make sure the appropriate variant of ~Inner() is emitted.
// CHECK: {{^}}define{{.*}} void @_ZN5OuterD2Ev
// CHECK: call void @_ZN5InnerIcED2Ev
// CHECK: {{^}}define linkonce_odr void @_ZN5InnerIcED2Ev
// CHECK: {{^}}define{{.*}} {{void|ptr}} @_ZN5OuterD2Ev
// CHECK: call{{.*}} {{void|ptr}} @_ZN5InnerIcED2Ev
// CHECK: {{^}}define linkonce_odr{{.*}} {{void|ptr}} @_ZN5InnerIcED2Ev

Outer::~Outer() { }
42 changes: 42 additions & 0 deletions llvm/include/llvm/Analysis/TapirTaskInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Instruction.h"
Expand Down Expand Up @@ -304,6 +305,17 @@ class Spindle {
DenseBlockSet.insert(&B);
}

/// Raw method to remove block B from this spindle.
void removeBlock(BasicBlock &B) {
DenseBlockSet.erase(&B);
for (auto Iter = Blocks.begin(); Iter != Blocks.end(); ++Iter) {
if (*Iter == &B) {
Blocks.erase(Iter);
break;
}
}
}

// Returns true if the basic block B predeces this spindle.
bool blockPrecedesSpindle(const BasicBlock *B) const {
for (const BasicBlock *SB : successors(B))
Expand Down Expand Up @@ -1456,6 +1468,27 @@ class TaskInfo {
SpindleMap[S] = T;
}

// Move spindle S from its task to that task's parent.
//
// NOTE: The resulting TaskInfo may not exactly match the state of a freshly
// computed TaskInfo.
void moveSpindlesToParent(Task *T) {
// Currently this method simply adds T's spindles to T's parent task
// and removes those spindles from T.
// TODO: Update Spindle types and edges.
Task *Parent = T->getParentTask();
// Add all spindles to parent task.
for (Spindle *S : T->Spindles) {
Parent->addSpindle(*S);
S->setParentTask(Parent);
SpindleMap[S] = Parent;
}

// Remove all spindles from this task.
while (!T->Spindles.empty())
T->Spindles.pop_back();
}

// Add spindle S to task T, where S is a shared exception-handling spindle
// among subtasks of T.
void addEHSpindleToTask(Spindle *S, Task *T) {
Expand All @@ -1472,6 +1505,15 @@ class TaskInfo {
BBMap[&B] = S;
}

// Remove basic block B from its spindle.
void removeBlock(BasicBlock &B) {
if (!BBMap.count(&B))
return;
Spindle *S = BBMap[&B];
S->removeBlock(B);
BBMap.erase(&B);
}

// Associate a task T with the spindle TFSpindle that creates its taskframe.
void AssociateTaskFrameWithUser(Task *T, Spindle *TFSpindle) {
TFSpindle->TaskFrameUser = T;
Expand Down
8 changes: 5 additions & 3 deletions llvm/include/llvm/Transforms/Utils/TapirUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ bool MoveStaticAllocasInBlock(BasicBlock *Entry, BasicBlock *Block,

/// Inline any taskframe.resume markers associated with the given taskframe. If
/// \p DT is provided, then it will be updated to reflect the CFG changes.
void InlineTaskFrameResumes(Value *TaskFrame, DominatorTree *DT = nullptr);
void InlineTaskFrameResumes(Value *TaskFrame, DominatorTree *DT = nullptr,
TaskInfo *TI = nullptr);

/// Clone exception-handling blocks EHBlocksToClone, with predecessors
/// EHBlockPreds in a given task. Updates EHBlockPreds to point at the cloned
Expand Down Expand Up @@ -131,7 +132,8 @@ void SerializeDetach(DetachInst *DI, BasicBlock *ParentEntry,
SmallPtrSetImpl<LandingPadInst *> *InlinedLPads,
SmallVectorImpl<Instruction *> *DetachedRethrows,
bool ReplaceWithTaskFrame = false,
DominatorTree *DT = nullptr, LoopInfo *LI = nullptr);
DominatorTree *DT = nullptr, TaskInfo *TI = nullptr,
LoopInfo *LI = nullptr);

/// Analyze a task T for serialization. Gets the reattaches, landing pads, and
/// detached rethrows that need special handling during serialization.
Expand All @@ -145,7 +147,7 @@ void AnalyzeTaskForSerialization(
/// Serialize the detach DI that spawns task T. If \p DT is provided, then it
/// will be updated to reflect the CFG changes.
void SerializeDetach(DetachInst *DI, Task *T, bool ReplaceWithTaskFrame = false,
DominatorTree *DT = nullptr);
DominatorTree *DT = nullptr, TaskInfo *TI = nullptr);

/// Get the entry basic block to the detached context that contains
/// the specified block.
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/Transforms/Utils/TaskSimplify.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class TaskSimplifyPass : public PassInfoMixin<TaskSimplifyPass> {
bool simplifySyncs(Task *T, MaybeParallelTasks &MPTasks);

/// Simplify the specified task T.
bool simplifyTask(Task *T);
bool simplifyTask(Task *T, TaskInfo &TI, DominatorTree &DT);

/// Simplify the taskframes analyzed by TapirTaskInfo TI.
bool simplifyTaskFrames(TaskInfo &TI, DominatorTree &DT);
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Tapir/LoopStripMine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1099,7 +1099,7 @@ Loop *llvm::StripMineLoop(Loop *L, unsigned Count, bool AllowExpensiveTripCount,
SerializeDetach(ClonedDI, ParentEntry, EHCont, EHContLPadVal,
ClonedReattaches, &ClonedEHBlocks, &ClonedEHBlockPreds,
&ClonedInlinedLPads, &ClonedDetachedRethrows,
NeedToInsertTaskFrame, DT, LI);
NeedToInsertTaskFrame, DT, nullptr, LI);
}

// Detach the stripmined loop.
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Transforms/Utils/InlineFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -675,8 +675,8 @@ static void HandleInlinedTasksHelper(
}

// Promote any calls in the block to invokes.
if (BasicBlock *NewBB = HandleCallsInBlockInlinedThroughInvoke(
BB, UnwindEdge)) {
if (BasicBlock *NewBB =
HandleCallsInBlockInlinedThroughInvoke(BB, UnwindEdge)) {
// If this is the topmost invocation of HandleInlinedTasksHelper, update
// any PHI nodes in the exceptional block to indicate that there is now a
// new entry in them.
Expand Down Expand Up @@ -745,7 +745,7 @@ static void HandleInlinedTasksHelper(
Invoke.addIncomingPHIValuesFor(SubTaskUnwindEdge);
}

} else if (Visited.insert(DI->getUnwindDest()).second) {
} else if (!Visited.contains(DI->getUnwindDest())) {
// If the detach-unwind isn't dead, add it to the worklist.
Worklist.push_back(DI->getUnwindDest());
}
Expand Down
54 changes: 36 additions & 18 deletions llvm/lib/Transforms/Utils/TapirUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,11 +387,16 @@ class LandingPadInliningInfo {

/// Dominator tree to update.
DominatorTree *DT = nullptr;

/// TaskInfo to update.
TaskInfo *TI = nullptr;

public:
LandingPadInliningInfo(DetachInst *DI, BasicBlock *EHContinue,
Value *LPadValInEHContinue,
DominatorTree *DT = nullptr)
: OuterResumeDest(EHContinue), SpawnerLPad(LPadValInEHContinue), DT(DT) {
DominatorTree *DT = nullptr, TaskInfo *TI = nullptr)
: OuterResumeDest(EHContinue), SpawnerLPad(LPadValInEHContinue), DT(DT),
TI(TI) {
// Find the predecessor block of OuterResumeDest.
BasicBlock *DetachBB = DI->getParent();
BasicBlock *DetachUnwind = DI->getUnwindDest();
Expand All @@ -414,9 +419,9 @@ class LandingPadInliningInfo {
}

LandingPadInliningInfo(InvokeInst *TaskFrameResume,
DominatorTree *DT = nullptr)
DominatorTree *DT = nullptr, TaskInfo *TI = nullptr)
: OuterResumeDest(TaskFrameResume->getUnwindDest()),
SpawnerLPad(TaskFrameResume->getLandingPadInst()), DT(DT) {
SpawnerLPad(TaskFrameResume->getLandingPadInst()), DT(DT), TI(TI) {
// If there are PHI nodes in the unwind destination block, we need to keep
// track of which values came into them from the detach before removing the
// edge from this block.
Expand Down Expand Up @@ -484,6 +489,8 @@ BasicBlock *LandingPadInliningInfo::getInnerResumeDest() {
for (DomTreeNode *I : Children)
DT->changeImmediateDominator(I, NewNode);
}
if (TI)
TI->addBlockToSpindle(*InnerResumeDest, TI->getSpindleFor(OuterResumeDest));

// The number of incoming edges we expect to the inner landing pad.
const unsigned PHICapacity = 2;
Expand Down Expand Up @@ -571,11 +578,15 @@ void LandingPadInliningInfo::forwardTaskResume(InvokeInst *TR) {
if (NormalDest) {
for (BasicBlock *Succ : successors(NormalDest))
maybeRemovePredecessor(Succ, NormalDest);
if (TI)
TI->removeBlock(*NormalDest);
NormalDest->eraseFromParent();
}
if (UnwindDest) {
for (BasicBlock *Succ : successors(UnwindDest))
maybeRemovePredecessor(Succ, UnwindDest);
if (TI)
TI->removeBlock(*UnwindDest);
UnwindDest->eraseFromParent();
}
}
Expand All @@ -584,8 +595,8 @@ static void handleDetachedLandingPads(
DetachInst *DI, BasicBlock *EHContinue, Value *LPadValInEHContinue,
SmallPtrSetImpl<LandingPadInst *> &InlinedLPads,
SmallVectorImpl<Instruction *> &DetachedRethrows,
DominatorTree *DT = nullptr) {
LandingPadInliningInfo DetUnwind(DI, EHContinue, LPadValInEHContinue, DT);
DominatorTree *DT = nullptr, TaskInfo *TI = nullptr) {
LandingPadInliningInfo DetUnwind(DI, EHContinue, LPadValInEHContinue, DT, TI);

// Append the clauses from the outer landing pad instruction into the inlined
// landing pad instructions.
Expand Down Expand Up @@ -815,13 +826,14 @@ static void getTaskFrameLandingPads(
// Helper method to handle a given taskframe.resume.
static void handleTaskFrameResume(Value *TaskFrame,
Instruction *TaskFrameResume,
DominatorTree *DT = nullptr) {
DominatorTree *DT = nullptr,
TaskInfo *TI = nullptr) {
// Get landingpads to inline.
SmallPtrSet<LandingPadInst *, 1> InlinedLPads;
getTaskFrameLandingPads(TaskFrame, TaskFrameResume, InlinedLPads);

InvokeInst *TFR = cast<InvokeInst>(TaskFrameResume);
LandingPadInliningInfo TFResumeDest(TFR, DT);
LandingPadInliningInfo TFResumeDest(TFR, DT, TI);

// Append the clauses from the outer landing pad instruction into the inlined
// landing pad instructions.
Expand All @@ -839,7 +851,8 @@ static void handleTaskFrameResume(Value *TaskFrame,
TFResumeDest.forwardTaskResume(TFR);
}

void llvm::InlineTaskFrameResumes(Value *TaskFrame, DominatorTree *DT) {
void llvm::InlineTaskFrameResumes(Value *TaskFrame, DominatorTree *DT,
TaskInfo *TI) {
SmallVector<Instruction *, 1> TaskFrameResumes;
// Record all taskframe.resume markers that use TaskFrame.
for (User *U : TaskFrame->users())
Expand All @@ -849,20 +862,20 @@ void llvm::InlineTaskFrameResumes(Value *TaskFrame, DominatorTree *DT) {

// Handle all taskframe.resume markers.
for (Instruction *TFR : TaskFrameResumes)
handleTaskFrameResume(TaskFrame, TFR, DT);
handleTaskFrameResume(TaskFrame, TFR, DT, TI);
}

static void startSerializingTaskFrame(Value *TaskFrame,
SmallVectorImpl<Instruction *> &ToErase,
DominatorTree *DT,
DominatorTree *DT, TaskInfo *TI,
bool PreserveTaskFrame) {
for (User *U : TaskFrame->users())
if (Instruction *UI = dyn_cast<Instruction>(U))
if (isTapirIntrinsic(Intrinsic::taskframe_use, UI))
ToErase.push_back(UI);

if (!PreserveTaskFrame)
InlineTaskFrameResumes(TaskFrame, DT);
InlineTaskFrameResumes(TaskFrame, DT, TI);
}

void llvm::SerializeDetach(DetachInst *DI, BasicBlock *ParentEntry,
Expand All @@ -873,7 +886,9 @@ void llvm::SerializeDetach(DetachInst *DI, BasicBlock *ParentEntry,
SmallPtrSetImpl<LandingPadInst *> *InlinedLPads,
SmallVectorImpl<Instruction *> *DetachedRethrows,
bool ReplaceWithTaskFrame, DominatorTree *DT,
LoopInfo *LI) {
TaskInfo *TI, LoopInfo *LI) {
LLVM_DEBUG(dbgs() << "Serializing detach " << *DI << "\n");

BasicBlock *Spawner = DI->getParent();
BasicBlock *TaskEntry = DI->getDetached();
BasicBlock *Continue = DI->getContinue();
Expand All @@ -885,7 +900,7 @@ void llvm::SerializeDetach(DetachInst *DI, BasicBlock *ParentEntry,
SmallVector<Instruction *, 8> ToErase;
Value *TaskFrame = getTaskFrameUsed(TaskEntry);
if (TaskFrame)
startSerializingTaskFrame(TaskFrame, ToErase, DT, ReplaceWithTaskFrame);
startSerializingTaskFrame(TaskFrame, ToErase, DT, TI, ReplaceWithTaskFrame);

// Clone any EH blocks that need cloning.
if (EHBlocksToClone) {
Expand Down Expand Up @@ -952,7 +967,7 @@ void llvm::SerializeDetach(DetachInst *DI, BasicBlock *ParentEntry,
} else {
// Otherwise, "inline" the detached landingpads.
handleDetachedLandingPads(DI, EHContinue, LPadValInEHContinue,
*InlinedLPads, *DetachedRethrows, DT);
*InlinedLPads, *DetachedRethrows, DT, TI);
}
}

Expand Down Expand Up @@ -1059,7 +1074,7 @@ void llvm::AnalyzeTaskForSerialization(
/// Serialize the detach DI that spawns task T. If provided, the dominator tree
/// DT will be updated to reflect the serialization.
void llvm::SerializeDetach(DetachInst *DI, Task *T, bool ReplaceWithTaskFrame,
DominatorTree *DT) {
DominatorTree *DT, TaskInfo *TI) {
assert(DI && "SerializeDetach given nullptr for detach.");
assert(DI == T->getDetach() && "Task and detach arguments do not match.");
SmallVector<BasicBlock *, 4> EHBlocksToClone;
Expand All @@ -1078,7 +1093,9 @@ void llvm::SerializeDetach(DetachInst *DI, Task *T, bool ReplaceWithTaskFrame,
}
SerializeDetach(DI, T->getParentTask()->getEntry(), EHContinue, LPadVal,
Reattaches, &EHBlocksToClone, &EHBlockPreds, &InlinedLPads,
&DetachedRethrows, ReplaceWithTaskFrame, DT);
&DetachedRethrows, ReplaceWithTaskFrame, DT, TI);
if (TI)
TI->moveSpindlesToParent(T);
}

static bool isCanonicalTaskFrameEnd(const Instruction *TFEnd) {
Expand Down Expand Up @@ -2260,7 +2277,8 @@ void llvm::eraseTaskFrame(Value *TaskFrame, DominatorTree *DT) {
for (User *U : TaskFrame->users()) {
if (Instruction *UI = dyn_cast<Instruction>(U))
if (isTapirIntrinsic(Intrinsic::taskframe_use, UI) ||
isTapirIntrinsic(Intrinsic::taskframe_end, UI))
isTapirIntrinsic(Intrinsic::taskframe_end, UI) ||
isTapirIntrinsic(Intrinsic::taskframe_resume, UI))
ToErase.push_back(UI);
}

Expand Down
Loading
Loading