Skip to content

Commit 3aac953

Browse files
committed
Revert "[OpenMP][IRBuilder] Perform finalization (incl. outlining) late"
This reverts commit 8a56d64. Will be recommitted once the clang test problem is addressed.
1 parent d1b393d commit 3aac953

File tree

5 files changed

+108
-169
lines changed

5 files changed

+108
-169
lines changed

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
#include "clang/Basic/TargetInfo.h"
3333
#include "clang/CodeGen/CGFunctionInfo.h"
3434
#include "clang/Frontend/FrontendDiagnostic.h"
35-
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
3635
#include "llvm/IR/DataLayout.h"
3736
#include "llvm/IR/Dominators.h"
3837
#include "llvm/IR/FPEnv.h"
@@ -105,14 +104,6 @@ CodeGenFunction::~CodeGenFunction() {
105104

106105
if (getLangOpts().OpenMP && CurFn)
107106
CGM.getOpenMPRuntime().functionFinished(*this);
108-
109-
// If we have an OpenMPIRBuilder we want to finalize functions (incl.
110-
// outlining etc) at some point. Doing it once the function codegen is done
111-
// seems to be a reasonable spot. We do it here, as opposed to the deletion
112-
// time of the CodeGenModule, because we have to ensure the IR has not yet
113-
// been "emitted" to the outside, thus, modifications are still sensible.
114-
if (llvm::OpenMPIRBuilder *OMPBuilder = CGM.getOpenMPIRBuilder())
115-
OMPBuilder->finalize();
116107
}
117108

118109
// Map the LangOption for rounding mode into

llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ class OpenMPIRBuilder {
3434
/// before any other method and only once!
3535
void initialize();
3636

37-
/// Finalize the underlying module, e.g., by outlining regions.
38-
void finalize();
39-
4037
/// Add attributes known for \p FnID to \p Fn.
4138
void addAttributes(omp::RuntimeFunction FnID, Function &Fn);
4239

@@ -257,20 +254,6 @@ class OpenMPIRBuilder {
257254

258255
/// Map to remember existing ident_t*.
259256
DenseMap<std::pair<Constant *, uint64_t>, GlobalVariable *> IdentMap;
260-
261-
/// Helper that contains information about regions we need to outline
262-
/// during finalization.
263-
struct OutlineInfo {
264-
SmallVector<BasicBlock *, 32> Blocks;
265-
using PostOutlineCBTy = std::function<void(Function &)>;
266-
PostOutlineCBTy PostOutlineCB;
267-
};
268-
269-
/// Collection of regions that need to be outlined during finalization.
270-
SmallVector<OutlineInfo, 16> OutlineInfos;
271-
272-
/// Add a new region that will be outlined later.
273-
void addOutlineInfo(OutlineInfo &&OI) { OutlineInfos.emplace_back(OI); }
274257
};
275258

276259
} // end namespace llvm

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 95 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -93,55 +93,6 @@ Function *OpenMPIRBuilder::getOrCreateRuntimeFunction(RuntimeFunction FnID) {
9393

9494
void OpenMPIRBuilder::initialize() { initializeTypes(M); }
9595

96-
void OpenMPIRBuilder::finalize() {
97-
for (OutlineInfo &OI : OutlineInfos) {
98-
assert(!OI.Blocks.empty() &&
99-
"Outlined regions should have at least a single block!");
100-
BasicBlock *RegEntryBB = OI.Blocks.front();
101-
Function *OuterFn = RegEntryBB->getParent();
102-
CodeExtractorAnalysisCache CEAC(*OuterFn);
103-
CodeExtractor Extractor(OI.Blocks, /* DominatorTree */ nullptr,
104-
/* AggregateArgs */ false,
105-
/* BlockFrequencyInfo */ nullptr,
106-
/* BranchProbabilityInfo */ nullptr,
107-
/* AssumptionCache */ nullptr,
108-
/* AllowVarArgs */ true,
109-
/* AllowAlloca */ true,
110-
/* Suffix */ ".omp_par");
111-
112-
LLVM_DEBUG(dbgs() << "Before outlining: " << *OuterFn << "\n");
113-
114-
Function *OutlinedFn = Extractor.extractCodeRegion(CEAC);
115-
116-
LLVM_DEBUG(dbgs() << "After outlining: " << *OuterFn << "\n");
117-
LLVM_DEBUG(dbgs() << " Outlined function: " << *OutlinedFn << "\n");
118-
119-
// For compability with the clang CG we move the outlined function after the
120-
// one with the parallel region.
121-
OutlinedFn->removeFromParent();
122-
M.getFunctionList().insertAfter(OuterFn->getIterator(), OutlinedFn);
123-
124-
// Remove the artificial entry introduced by the extractor right away, we
125-
// made our own entry block after all.
126-
{
127-
BasicBlock &ArtificialEntry = OutlinedFn->getEntryBlock();
128-
assert(ArtificialEntry.getUniqueSuccessor() == RegEntryBB);
129-
assert(RegEntryBB->getUniquePredecessor() == &ArtificialEntry);
130-
RegEntryBB->moveBefore(&ArtificialEntry);
131-
ArtificialEntry.eraseFromParent();
132-
}
133-
assert(&OutlinedFn->getEntryBlock() == RegEntryBB);
134-
assert(OutlinedFn && OutlinedFn->getNumUses() == 1);
135-
136-
// Run a user callback, e.g. to add attributes.
137-
if (OI.PostOutlineCB)
138-
OI.PostOutlineCB(*OutlinedFn);
139-
}
140-
141-
// Allow finalize to be called multiple times.
142-
OutlineInfos.clear();
143-
}
144-
14596
Value *OpenMPIRBuilder::getOrCreateIdent(Constant *SrcLocStr,
14697
IdentFlag LocFlags) {
14798
// Enable "C-mode".
@@ -464,33 +415,32 @@ IRBuilder<>::InsertPoint OpenMPIRBuilder::CreateParallel(
464415
// PRegionExitBB <- A common exit to simplify block collection.
465416
//
466417

467-
LLVM_DEBUG(dbgs() << "Before body codegen: " << *OuterFn << "\n");
418+
LLVM_DEBUG(dbgs() << "Before body codegen: " << *UI->getFunction() << "\n");
468419

469420
// Let the caller create the body.
470421
assert(BodyGenCB && "Expected body generation callback!");
471422
InsertPointTy CodeGenIP(PRegBodyBB, PRegBodyBB->begin());
472423
BodyGenCB(AllocaIP, CodeGenIP, *PRegPreFiniBB);
473424

474-
LLVM_DEBUG(dbgs() << "After body codegen: " << *OuterFn << "\n");
425+
LLVM_DEBUG(dbgs() << "After body codegen: " << *UI->getFunction() << "\n");
475426

476-
OutlineInfo OI;
477427
SmallPtrSet<BasicBlock *, 32> ParallelRegionBlockSet;
478-
SmallVector<BasicBlock *, 32> Worklist;
428+
SmallVector<BasicBlock *, 32> ParallelRegionBlocks, Worklist;
479429
ParallelRegionBlockSet.insert(PRegEntryBB);
480430
ParallelRegionBlockSet.insert(PRegExitBB);
481431

482432
// Collect all blocks in-between PRegEntryBB and PRegExitBB.
483433
Worklist.push_back(PRegEntryBB);
484434
while (!Worklist.empty()) {
485435
BasicBlock *BB = Worklist.pop_back_val();
486-
OI.Blocks.push_back(BB);
436+
ParallelRegionBlocks.push_back(BB);
487437
for (BasicBlock *SuccBB : successors(BB))
488438
if (ParallelRegionBlockSet.insert(SuccBB).second)
489439
Worklist.push_back(SuccBB);
490440
}
491441

492442
CodeExtractorAnalysisCache CEAC(*OuterFn);
493-
CodeExtractor Extractor(OI.Blocks, /* DominatorTree */ nullptr,
443+
CodeExtractor Extractor(ParallelRegionBlocks, /* DominatorTree */ nullptr,
494444
/* AggregateArgs */ false,
495445
/* BlockFrequencyInfo */ nullptr,
496446
/* BranchProbabilityInfo */ nullptr,
@@ -505,7 +455,7 @@ IRBuilder<>::InsertPoint OpenMPIRBuilder::CreateParallel(
505455
Extractor.findAllocas(CEAC, SinkingCands, HoistingCands, CommonExit);
506456
Extractor.findInputsOutputs(Inputs, Outputs, SinkingCands);
507457

508-
LLVM_DEBUG(dbgs() << "Before privatization: " << *OuterFn << "\n");
458+
LLVM_DEBUG(dbgs() << "Before privatization: " << *UI->getFunction() << "\n");
509459

510460
FunctionCallee TIDRTLFn =
511461
getOrCreateRuntimeFunction(OMPRTL___kmpc_global_thread_num);
@@ -546,12 +496,56 @@ IRBuilder<>::InsertPoint OpenMPIRBuilder::CreateParallel(
546496
PrivHelper(*Output);
547497
}
548498

549-
LLVM_DEBUG(dbgs() << "After privatization: " << *OuterFn << "\n");
499+
LLVM_DEBUG(dbgs() << "After privatization: " << *UI->getFunction() << "\n");
550500
LLVM_DEBUG({
551-
for (auto *BB : OI.Blocks)
501+
for (auto *BB : ParallelRegionBlocks)
552502
dbgs() << " PBR: " << BB->getName() << "\n";
553503
});
554504

505+
// Add some known attributes to the outlined function.
506+
Function *OutlinedFn = Extractor.extractCodeRegion(CEAC);
507+
OutlinedFn->addParamAttr(0, Attribute::NoAlias);
508+
OutlinedFn->addParamAttr(1, Attribute::NoAlias);
509+
OutlinedFn->addFnAttr(Attribute::NoUnwind);
510+
OutlinedFn->addFnAttr(Attribute::NoRecurse);
511+
512+
LLVM_DEBUG(dbgs() << "After outlining: " << *UI->getFunction() << "\n");
513+
LLVM_DEBUG(dbgs() << " Outlined function: " << *OutlinedFn << "\n");
514+
515+
// For compability with the clang CG we move the outlined function after the
516+
// one with the parallel region.
517+
OutlinedFn->removeFromParent();
518+
M.getFunctionList().insertAfter(OuterFn->getIterator(), OutlinedFn);
519+
520+
// Remove the artificial entry introduced by the extractor right away, we
521+
// made our own entry block after all.
522+
{
523+
BasicBlock &ArtificialEntry = OutlinedFn->getEntryBlock();
524+
assert(ArtificialEntry.getUniqueSuccessor() == PRegEntryBB);
525+
assert(PRegEntryBB->getUniquePredecessor() == &ArtificialEntry);
526+
PRegEntryBB->moveBefore(&ArtificialEntry);
527+
ArtificialEntry.eraseFromParent();
528+
}
529+
LLVM_DEBUG(dbgs() << "PP Outlined function: " << *OutlinedFn << "\n");
530+
assert(&OutlinedFn->getEntryBlock() == PRegEntryBB);
531+
532+
assert(OutlinedFn && OutlinedFn->getNumUses() == 1);
533+
assert(OutlinedFn->arg_size() >= 2 &&
534+
"Expected at least tid and bounded tid as arguments");
535+
unsigned NumCapturedVars = OutlinedFn->arg_size() - /* tid & bounded tid */ 2;
536+
537+
CallInst *CI = cast<CallInst>(OutlinedFn->user_back());
538+
CI->getParent()->setName("omp_parallel");
539+
Builder.SetInsertPoint(CI);
540+
541+
// Build call __kmpc_fork_call(Ident, n, microtask, var1, .., varn);
542+
Value *ForkCallArgs[] = {Ident, Builder.getInt32(NumCapturedVars),
543+
Builder.CreateBitCast(OutlinedFn, ParallelTaskPtr)};
544+
545+
SmallVector<Value *, 16> RealArgs;
546+
RealArgs.append(std::begin(ForkCallArgs), std::end(ForkCallArgs));
547+
RealArgs.append(CI->arg_begin() + /* tid & bound tid */ 2, CI->arg_end());
548+
555549
FunctionCallee RTLFn = getOrCreateRuntimeFunction(OMPRTL___kmpc_fork_call);
556550
if (auto *F = dyn_cast<llvm::Function>(RTLFn.getCallee())) {
557551
if (!F->hasMetadata(llvm::LLVMContext::MD_callback)) {
@@ -564,104 +558,75 @@ IRBuilder<>::InsertPoint OpenMPIRBuilder::CreateParallel(
564558
// callback callee.
565559
F->addMetadata(
566560
llvm::LLVMContext::MD_callback,
567-
*llvm::MDNode::get(
568-
Ctx, {MDB.createCallbackEncoding(2, {-1, -1},
569-
/* VarArgsArePassed */ true)}));
561+
*llvm::MDNode::get(Ctx, {MDB.createCallbackEncoding(
562+
2, {-1, -1},
563+
/* VarArgsArePassed */ true)}));
570564
}
571565
}
572566

573-
OI.PostOutlineCB = [=](Function &OutlinedFn) {
574-
// Add some known attributes.
575-
OutlinedFn.addParamAttr(0, Attribute::NoAlias);
576-
OutlinedFn.addParamAttr(1, Attribute::NoAlias);
577-
OutlinedFn.addFnAttr(Attribute::NoUnwind);
578-
OutlinedFn.addFnAttr(Attribute::NoRecurse);
579-
580-
assert(OutlinedFn.arg_size() >= 2 &&
581-
"Expected at least tid and bounded tid as arguments");
582-
unsigned NumCapturedVars =
583-
OutlinedFn.arg_size() - /* tid & bounded tid */ 2;
584-
585-
CallInst *CI = cast<CallInst>(OutlinedFn.user_back());
586-
CI->getParent()->setName("omp_parallel");
587-
Builder.SetInsertPoint(CI);
588-
589-
// Build call __kmpc_fork_call(Ident, n, microtask, var1, .., varn);
590-
Value *ForkCallArgs[] = {
591-
Ident, Builder.getInt32(NumCapturedVars),
592-
Builder.CreateBitCast(&OutlinedFn, ParallelTaskPtr)};
593-
594-
SmallVector<Value *, 16> RealArgs;
595-
RealArgs.append(std::begin(ForkCallArgs), std::end(ForkCallArgs));
596-
RealArgs.append(CI->arg_begin() + /* tid & bound tid */ 2, CI->arg_end());
567+
Builder.CreateCall(RTLFn, RealArgs);
597568

598-
Builder.CreateCall(RTLFn, RealArgs);
569+
LLVM_DEBUG(dbgs() << "With fork_call placed: "
570+
<< *Builder.GetInsertBlock()->getParent() << "\n");
599571

600-
LLVM_DEBUG(dbgs() << "With fork_call placed: "
601-
<< *Builder.GetInsertBlock()->getParent() << "\n");
602-
603-
InsertPointTy ExitIP(PRegExitBB, PRegExitBB->end());
604-
605-
// Initialize the local TID stack location with the argument value.
606-
Builder.SetInsertPoint(PrivTID);
607-
Function::arg_iterator OutlinedAI = OutlinedFn.arg_begin();
608-
Builder.CreateStore(Builder.CreateLoad(OutlinedAI), PrivTIDAddr);
572+
InsertPointTy AfterIP(UI->getParent(), UI->getParent()->end());
573+
InsertPointTy ExitIP(PRegExitBB, PRegExitBB->end());
574+
UI->eraseFromParent();
609575

610-
// If no "if" clause was present we do not need the call created during
611-
// outlining, otherwise we reuse it in the serialized parallel region.
612-
if (!ElseTI) {
613-
CI->eraseFromParent();
614-
} else {
576+
// Initialize the local TID stack location with the argument value.
577+
Builder.SetInsertPoint(PrivTID);
578+
Function::arg_iterator OutlinedAI = OutlinedFn->arg_begin();
579+
Builder.CreateStore(Builder.CreateLoad(OutlinedAI), PrivTIDAddr);
615580

616-
// If an "if" clause was present we are now generating the serialized
617-
// version into the "else" branch.
618-
Builder.SetInsertPoint(ElseTI);
581+
// If no "if" clause was present we do not need the call created during
582+
// outlining, otherwise we reuse it in the serialized parallel region.
583+
if (!ElseTI) {
584+
CI->eraseFromParent();
585+
} else {
619586

620-
// Build calls __kmpc_serialized_parallel(&Ident, GTid);
621-
Value *SerializedParallelCallArgs[] = {Ident, ThreadID};
622-
Builder.CreateCall(
623-
getOrCreateRuntimeFunction(OMPRTL___kmpc_serialized_parallel),
624-
SerializedParallelCallArgs);
587+
// If an "if" clause was present we are now generating the serialized
588+
// version into the "else" branch.
589+
Builder.SetInsertPoint(ElseTI);
625590

626-
// OutlinedFn(&GTid, &zero, CapturedStruct);
627-
CI->removeFromParent();
628-
Builder.Insert(CI);
591+
// Build calls __kmpc_serialized_parallel(&Ident, GTid);
592+
Value *SerializedParallelCallArgs[] = {Ident, ThreadID};
593+
Builder.CreateCall(
594+
getOrCreateRuntimeFunction(OMPRTL___kmpc_serialized_parallel),
595+
SerializedParallelCallArgs);
629596

630-
// __kmpc_end_serialized_parallel(&Ident, GTid);
631-
Value *EndArgs[] = {Ident, ThreadID};
632-
Builder.CreateCall(
633-
getOrCreateRuntimeFunction(OMPRTL___kmpc_end_serialized_parallel),
634-
EndArgs);
597+
// OutlinedFn(&GTid, &zero, CapturedStruct);
598+
CI->removeFromParent();
599+
Builder.Insert(CI);
635600

636-
LLVM_DEBUG(dbgs() << "With serialized parallel region: "
637-
<< *Builder.GetInsertBlock()->getParent() << "\n");
638-
}
601+
// __kmpc_end_serialized_parallel(&Ident, GTid);
602+
Value *EndArgs[] = {Ident, ThreadID};
603+
Builder.CreateCall(
604+
getOrCreateRuntimeFunction(OMPRTL___kmpc_end_serialized_parallel),
605+
EndArgs);
639606

640-
for (Instruction *I : ToBeDeleted)
641-
I->eraseFromParent();
642-
};
607+
LLVM_DEBUG(dbgs() << "With serialized parallel region: "
608+
<< *Builder.GetInsertBlock()->getParent() << "\n");
609+
}
643610

644611
// Adjust the finalization stack, verify the adjustment, and call the
645-
// finalize function a last time to finalize values between the pre-fini
646-
// block and the exit block if we left the parallel "the normal way".
612+
// finalize function a last time to finalize values between the pre-fini block
613+
// and the exit block if we left the parallel "the normal way".
647614
auto FiniInfo = FinalizationStack.pop_back_val();
648615
(void)FiniInfo;
649616
assert(FiniInfo.DK == OMPD_parallel &&
650617
"Unexpected finalization stack state!");
651618

652619
Instruction *PreFiniTI = PRegPreFiniBB->getTerminator();
653620
assert(PreFiniTI->getNumSuccessors() == 1 &&
654-
PreFiniTI->getSuccessor(0) == PRegExitBB &&
621+
PreFiniTI->getSuccessor(0)->size() == 1 &&
622+
isa<ReturnInst>(PreFiniTI->getSuccessor(0)->getTerminator()) &&
655623
"Unexpected CFG structure!");
656624

657625
InsertPointTy PreFiniIP(PRegPreFiniBB, PreFiniTI->getIterator());
658626
FiniCB(PreFiniIP);
659627

660-
InsertPointTy AfterIP(UI->getParent(), UI->getParent()->end());
661-
UI->eraseFromParent();
662-
663-
// Register the outlined info.
664-
addOutlineInfo(std::move(OI));
628+
for (Instruction *I : ToBeDeleted)
629+
I->eraseFromParent();
665630

666631
return AfterIP;
667632
}

llvm/lib/Transforms/Utils/CodeExtractor.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1405,7 +1405,11 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
14051405
DISubprogram *OldSP = OldFunc.getSubprogram();
14061406
LLVMContext &Ctx = OldFunc.getContext();
14071407

1408-
if (!OldSP) {
1408+
// See llvm.org/PR44560, OpenMP passes an invalid subprogram to CodeExtractor.
1409+
bool NeedWorkaroundForOpenMPIRBuilderBug =
1410+
OldSP && OldSP->getRetainedNodes()->isTemporary();
1411+
1412+
if (!OldSP || NeedWorkaroundForOpenMPIRBuilderBug) {
14091413
// Erase any debug info the new function contains.
14101414
stripDebugInfo(NewFunc);
14111415
// Make sure the old function doesn't contain any non-local metadata refs.

0 commit comments

Comments
 (0)