@@ -93,55 +93,6 @@ Function *OpenMPIRBuilder::getOrCreateRuntimeFunction(RuntimeFunction FnID) {
93
93
94
94
void OpenMPIRBuilder::initialize () { initializeTypes (M); }
95
95
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
-
145
96
Value *OpenMPIRBuilder::getOrCreateIdent (Constant *SrcLocStr,
146
97
IdentFlag LocFlags) {
147
98
// Enable "C-mode".
@@ -464,33 +415,32 @@ IRBuilder<>::InsertPoint OpenMPIRBuilder::CreateParallel(
464
415
// PRegionExitBB <- A common exit to simplify block collection.
465
416
//
466
417
467
- LLVM_DEBUG (dbgs () << " Before body codegen: " << *OuterFn << " \n " );
418
+ LLVM_DEBUG (dbgs () << " Before body codegen: " << *UI-> getFunction () << " \n " );
468
419
469
420
// Let the caller create the body.
470
421
assert (BodyGenCB && " Expected body generation callback!" );
471
422
InsertPointTy CodeGenIP (PRegBodyBB, PRegBodyBB->begin ());
472
423
BodyGenCB (AllocaIP, CodeGenIP, *PRegPreFiniBB);
473
424
474
- LLVM_DEBUG (dbgs () << " After body codegen: " << *OuterFn << " \n " );
425
+ LLVM_DEBUG (dbgs () << " After body codegen: " << *UI-> getFunction () << " \n " );
475
426
476
- OutlineInfo OI;
477
427
SmallPtrSet<BasicBlock *, 32 > ParallelRegionBlockSet;
478
- SmallVector<BasicBlock *, 32 > Worklist;
428
+ SmallVector<BasicBlock *, 32 > ParallelRegionBlocks, Worklist;
479
429
ParallelRegionBlockSet.insert (PRegEntryBB);
480
430
ParallelRegionBlockSet.insert (PRegExitBB);
481
431
482
432
// Collect all blocks in-between PRegEntryBB and PRegExitBB.
483
433
Worklist.push_back (PRegEntryBB);
484
434
while (!Worklist.empty ()) {
485
435
BasicBlock *BB = Worklist.pop_back_val ();
486
- OI. Blocks .push_back (BB);
436
+ ParallelRegionBlocks .push_back (BB);
487
437
for (BasicBlock *SuccBB : successors (BB))
488
438
if (ParallelRegionBlockSet.insert (SuccBB).second )
489
439
Worklist.push_back (SuccBB);
490
440
}
491
441
492
442
CodeExtractorAnalysisCache CEAC (*OuterFn);
493
- CodeExtractor Extractor (OI. Blocks , /* DominatorTree */ nullptr ,
443
+ CodeExtractor Extractor (ParallelRegionBlocks , /* DominatorTree */ nullptr ,
494
444
/* AggregateArgs */ false ,
495
445
/* BlockFrequencyInfo */ nullptr ,
496
446
/* BranchProbabilityInfo */ nullptr ,
@@ -505,7 +455,7 @@ IRBuilder<>::InsertPoint OpenMPIRBuilder::CreateParallel(
505
455
Extractor.findAllocas (CEAC, SinkingCands, HoistingCands, CommonExit);
506
456
Extractor.findInputsOutputs (Inputs, Outputs, SinkingCands);
507
457
508
- LLVM_DEBUG (dbgs () << " Before privatization: " << *OuterFn << " \n " );
458
+ LLVM_DEBUG (dbgs () << " Before privatization: " << *UI-> getFunction () << " \n " );
509
459
510
460
FunctionCallee TIDRTLFn =
511
461
getOrCreateRuntimeFunction (OMPRTL___kmpc_global_thread_num);
@@ -546,12 +496,56 @@ IRBuilder<>::InsertPoint OpenMPIRBuilder::CreateParallel(
546
496
PrivHelper (*Output);
547
497
}
548
498
549
- LLVM_DEBUG (dbgs () << " After privatization: " << *OuterFn << " \n " );
499
+ LLVM_DEBUG (dbgs () << " After privatization: " << *UI-> getFunction () << " \n " );
550
500
LLVM_DEBUG ({
551
- for (auto *BB : OI. Blocks )
501
+ for (auto *BB : ParallelRegionBlocks )
552
502
dbgs () << " PBR: " << BB->getName () << " \n " ;
553
503
});
554
504
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
+
555
549
FunctionCallee RTLFn = getOrCreateRuntimeFunction (OMPRTL___kmpc_fork_call);
556
550
if (auto *F = dyn_cast<llvm::Function>(RTLFn.getCallee ())) {
557
551
if (!F->hasMetadata (llvm::LLVMContext::MD_callback)) {
@@ -564,104 +558,75 @@ IRBuilder<>::InsertPoint OpenMPIRBuilder::CreateParallel(
564
558
// callback callee.
565
559
F->addMetadata (
566
560
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 )}));
570
564
}
571
565
}
572
566
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);
597
568
598
- Builder.CreateCall (RTLFn, RealArgs);
569
+ LLVM_DEBUG (dbgs () << " With fork_call placed: "
570
+ << *Builder.GetInsertBlock ()->getParent () << " \n " );
599
571
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 ();
609
575
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);
615
580
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 {
619
586
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);
625
590
626
- // OutlinedFn(>id, &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);
629
596
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(>id, &zero, CapturedStruct);
598
+ CI->removeFromParent ();
599
+ Builder.Insert (CI);
635
600
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);
639
606
640
- for (Instruction *I : ToBeDeleted)
641
- I-> eraseFromParent ( );
642
- };
607
+ LLVM_DEBUG ( dbgs () << " With serialized parallel region: "
608
+ << *Builder. GetInsertBlock ()-> getParent () << " \n " );
609
+ }
643
610
644
611
// 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".
647
614
auto FiniInfo = FinalizationStack.pop_back_val ();
648
615
(void )FiniInfo;
649
616
assert (FiniInfo.DK == OMPD_parallel &&
650
617
" Unexpected finalization stack state!" );
651
618
652
619
Instruction *PreFiniTI = PRegPreFiniBB->getTerminator ();
653
620
assert (PreFiniTI->getNumSuccessors () == 1 &&
654
- PreFiniTI->getSuccessor (0 ) == PRegExitBB &&
621
+ PreFiniTI->getSuccessor (0 )->size () == 1 &&
622
+ isa<ReturnInst>(PreFiniTI->getSuccessor (0 )->getTerminator ()) &&
655
623
" Unexpected CFG structure!" );
656
624
657
625
InsertPointTy PreFiniIP (PRegPreFiniBB, PreFiniTI->getIterator ());
658
626
FiniCB (PreFiniIP);
659
627
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 ();
665
630
666
631
return AfterIP;
667
632
}
0 commit comments