LLVM  11.0.0git
OMPIRBuilder.cpp
Go to the documentation of this file.
1 //===- OpenMPIRBuilder.cpp - Builder for LLVM-IR for OpenMP directives ----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 ///
10 /// This file implements the OpenMPIRBuilder class, which is used as a
11 /// convenient way to create LLVM instructions for OpenMP directives.
12 ///
13 //===----------------------------------------------------------------------===//
14 
16 
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/IR/CFG.h"
20 #include "llvm/IR/DebugInfo.h"
21 #include "llvm/IR/IRBuilder.h"
22 #include "llvm/IR/MDBuilder.h"
24 #include "llvm/Support/Error.h"
27 
28 #include <sstream>
29 
30 #define DEBUG_TYPE "openmp-ir-builder"
31 
32 using namespace llvm;
33 using namespace omp;
34 using namespace types;
35 
36 static cl::opt<bool>
37  OptimisticAttributes("openmp-ir-builder-optimistic-attributes", cl::Hidden,
38  cl::desc("Use optimistic attributes describing "
39  "'as-if' properties of runtime calls."),
40  cl::init(false));
41 
43  LLVMContext &Ctx = Fn.getContext();
44 
45 #define OMP_ATTRS_SET(VarName, AttrSet) AttributeSet VarName = AttrSet;
46 #include "llvm/Frontend/OpenMP/OMPKinds.def"
47 
48  // Add attributes to the new declaration.
49  switch (FnID) {
50 #define OMP_RTL_ATTRS(Enum, FnAttrSet, RetAttrSet, ArgAttrSets) \
51  case Enum: \
52  Fn.setAttributes( \
53  AttributeList::get(Ctx, FnAttrSet, RetAttrSet, ArgAttrSets)); \
54  break;
55 #include "llvm/Frontend/OpenMP/OMPKinds.def"
56  default:
57  // Attributes are optional.
58  break;
59  }
60 }
61 
64  FunctionType *FnTy = nullptr;
65  Function *Fn = nullptr;
66 
67  // Try to find the declation in the module first.
68  switch (FnID) {
69 #define OMP_RTL(Enum, Str, IsVarArg, ReturnType, ...) \
70  case Enum: \
71  FnTy = FunctionType::get(ReturnType, ArrayRef<Type *>{__VA_ARGS__}, \
72  IsVarArg); \
73  Fn = M.getFunction(Str); \
74  break;
75 #include "llvm/Frontend/OpenMP/OMPKinds.def"
76  }
77 
78  if (!Fn) {
79  // Create a new declaration if we need one.
80  switch (FnID) {
81 #define OMP_RTL(Enum, Str, ...) \
82  case Enum: \
83  Fn = Function::Create(FnTy, GlobalValue::ExternalLinkage, Str, M); \
84  break;
85 #include "llvm/Frontend/OpenMP/OMPKinds.def"
86  }
87 
88  // Add information if the runtime function takes a callback function
89  if (FnID == OMPRTL___kmpc_fork_call || FnID == OMPRTL___kmpc_fork_teams) {
90  if (!Fn->hasMetadata(LLVMContext::MD_callback)) {
91  LLVMContext &Ctx = Fn->getContext();
92  MDBuilder MDB(Ctx);
93  // Annotate the callback behavior of the runtime function:
94  // - The callback callee is argument number 2 (microtask).
95  // - The first two arguments of the callback callee are unknown (-1).
96  // - All variadic arguments to the runtime function are passed to the
97  // callback callee.
98  Fn->addMetadata(
99  LLVMContext::MD_callback,
101  2, {-1, -1}, /* VarArgsArePassed */ true)}));
102  }
103  }
104 
105  LLVM_DEBUG(dbgs() << "Created OpenMP runtime function " << Fn->getName()
106  << " with type " << *Fn->getFunctionType() << "\n");
107  addAttributes(FnID, *Fn);
108 
109  } else {
110  LLVM_DEBUG(dbgs() << "Found OpenMP runtime function " << Fn->getName()
111  << " with type " << *Fn->getFunctionType() << "\n");
112  }
113 
114  assert(Fn && "Failed to create OpenMP runtime function");
115 
116  // Cast the function to the expected type if necessary
118  return {FnTy, C};
119 }
120 
122  FunctionCallee RTLFn = getOrCreateRuntimeFunction(M, FnID);
123  auto *Fn = dyn_cast<llvm::Function>(RTLFn.getCallee());
124  assert(Fn && "Failed to create OpenMP runtime function pointer");
125  return Fn;
126 }
127 
129 
131  for (OutlineInfo &OI : OutlineInfos) {
132  assert(!OI.Blocks.empty() &&
133  "Outlined regions should have at least a single block!");
134  BasicBlock *RegEntryBB = OI.Blocks.front();
135  Function *OuterFn = RegEntryBB->getParent();
136  CodeExtractorAnalysisCache CEAC(*OuterFn);
137  CodeExtractor Extractor(OI.Blocks, /* DominatorTree */ nullptr,
138  /* AggregateArgs */ false,
139  /* BlockFrequencyInfo */ nullptr,
140  /* BranchProbabilityInfo */ nullptr,
141  /* AssumptionCache */ nullptr,
142  /* AllowVarArgs */ true,
143  /* AllowAlloca */ true,
144  /* Suffix */ ".omp_par");
145 
146  LLVM_DEBUG(dbgs() << "Before outlining: " << *OuterFn << "\n");
147  assert(Extractor.isEligible() &&
148  "Expected OpenMP outlining to be possible!");
149 
150  Function *OutlinedFn = Extractor.extractCodeRegion(CEAC);
151 
152  LLVM_DEBUG(dbgs() << "After outlining: " << *OuterFn << "\n");
153  LLVM_DEBUG(dbgs() << " Outlined function: " << *OutlinedFn << "\n");
154  assert(OutlinedFn->getReturnType()->isVoidTy() &&
155  "OpenMP outlined functions should not return a value!");
156 
157  // For compability with the clang CG we move the outlined function after the
158  // one with the parallel region.
159  OutlinedFn->removeFromParent();
160  M.getFunctionList().insertAfter(OuterFn->getIterator(), OutlinedFn);
161 
162  // Remove the artificial entry introduced by the extractor right away, we
163  // made our own entry block after all.
164  {
165  BasicBlock &ArtificialEntry = OutlinedFn->getEntryBlock();
166  assert(ArtificialEntry.getUniqueSuccessor() == RegEntryBB);
167  assert(RegEntryBB->getUniquePredecessor() == &ArtificialEntry);
168  RegEntryBB->moveBefore(&ArtificialEntry);
169  ArtificialEntry.eraseFromParent();
170  }
171  assert(&OutlinedFn->getEntryBlock() == RegEntryBB);
172  assert(OutlinedFn && OutlinedFn->getNumUses() == 1);
173 
174  // Run a user callback, e.g. to add attributes.
175  if (OI.PostOutlineCB)
176  OI.PostOutlineCB(*OutlinedFn);
177  }
178 
179  // Allow finalize to be called multiple times.
180  OutlineInfos.clear();
181 }
182 
184  IdentFlag LocFlags) {
185  // Enable "C-mode".
186  LocFlags |= OMP_IDENT_FLAG_KMPC;
187 
188  GlobalVariable *&DefaultIdent = IdentMap[{SrcLocStr, uint64_t(LocFlags)}];
189  if (!DefaultIdent) {
190  Constant *I32Null = ConstantInt::getNullValue(Int32);
191  Constant *IdentData[] = {I32Null,
192  ConstantInt::get(Int32, uint64_t(LocFlags)),
193  I32Null, I32Null, SrcLocStr};
194  Constant *Initializer = ConstantStruct::get(
195  cast<StructType>(IdentPtr->getPointerElementType()), IdentData);
196 
197  // Look for existing encoding of the location + flags, not needed but
198  // minimizes the difference to the existing solution while we transition.
199  for (GlobalVariable &GV : M.getGlobalList())
200  if (GV.getType() == IdentPtr && GV.hasInitializer())
201  if (GV.getInitializer() == Initializer)
202  return DefaultIdent = &GV;
203 
204  DefaultIdent = new GlobalVariable(M, IdentPtr->getPointerElementType(),
205  /* isConstant = */ false,
206  GlobalValue::PrivateLinkage, Initializer);
208  DefaultIdent->setAlignment(Align(8));
209  }
210  return DefaultIdent;
211 }
212 
214  Constant *&SrcLocStr = SrcLocStrMap[LocStr];
215  if (!SrcLocStr) {
216  Constant *Initializer =
217  ConstantDataArray::getString(M.getContext(), LocStr);
218 
219  // Look for existing encoding of the location, not needed but minimizes the
220  // difference to the existing solution while we transition.
221  for (GlobalVariable &GV : M.getGlobalList())
222  if (GV.isConstant() && GV.hasInitializer() &&
223  GV.getInitializer() == Initializer)
224  return SrcLocStr = ConstantExpr::getPointerCast(&GV, Int8Ptr);
225 
226  SrcLocStr = Builder.CreateGlobalStringPtr(LocStr);
227  }
228  return SrcLocStr;
229 }
230 
232  return getOrCreateSrcLocStr(";unknown;unknown;0;0;;");
233 }
234 
235 Constant *
237  DILocation *DIL = Loc.DL.get();
238  if (!DIL)
239  return getOrCreateDefaultSrcLocStr();
240  StringRef Filename =
241  !DIL->getFilename().empty() ? DIL->getFilename() : M.getName();
242  StringRef Function = DIL->getScope()->getSubprogram()->getName();
243  Function =
244  !Function.empty() ? Function : Loc.IP.getBlock()->getParent()->getName();
245  std::string LineStr = std::to_string(DIL->getLine());
246  std::string ColumnStr = std::to_string(DIL->getColumn());
247  std::stringstream SrcLocStr;
248  SrcLocStr << ";" << Filename.data() << ";" << Function.data() << ";"
249  << LineStr << ";" << ColumnStr << ";;";
250  return getOrCreateSrcLocStr(SrcLocStr.str());
251 }
252 
254  return Builder.CreateCall(
255  getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_global_thread_num), Ident,
256  "omp_global_thread_num");
257 }
258 
261  bool ForceSimpleCall, bool CheckCancelFlag) {
262  if (!updateToLocation(Loc))
263  return Loc.IP;
264  return emitBarrierImpl(Loc, DK, ForceSimpleCall, CheckCancelFlag);
265 }
266 
269  bool ForceSimpleCall, bool CheckCancelFlag) {
270  // Build call __kmpc_cancel_barrier(loc, thread_id) or
271  // __kmpc_barrier(loc, thread_id);
272 
273  IdentFlag BarrierLocFlags;
274  switch (Kind) {
275  case OMPD_for:
276  BarrierLocFlags = OMP_IDENT_FLAG_BARRIER_IMPL_FOR;
277  break;
278  case OMPD_sections:
279  BarrierLocFlags = OMP_IDENT_FLAG_BARRIER_IMPL_SECTIONS;
280  break;
281  case OMPD_single:
282  BarrierLocFlags = OMP_IDENT_FLAG_BARRIER_IMPL_SINGLE;
283  break;
284  case OMPD_barrier:
285  BarrierLocFlags = OMP_IDENT_FLAG_BARRIER_EXPL;
286  break;
287  default:
288  BarrierLocFlags = OMP_IDENT_FLAG_BARRIER_IMPL;
289  break;
290  }
291 
292  Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
293  Value *Args[] = {getOrCreateIdent(SrcLocStr, BarrierLocFlags),
294  getOrCreateThreadID(getOrCreateIdent(SrcLocStr))};
295 
296  // If we are in a cancellable parallel region, barriers are cancellation
297  // points.
298  // TODO: Check why we would force simple calls or to ignore the cancel flag.
299  bool UseCancelBarrier =
300  !ForceSimpleCall && isLastFinalizationInfoCancellable(OMPD_parallel);
301 
302  Value *Result =
303  Builder.CreateCall(getOrCreateRuntimeFunctionPtr(
304  UseCancelBarrier ? OMPRTL___kmpc_cancel_barrier
305  : OMPRTL___kmpc_barrier),
306  Args);
307 
308  if (UseCancelBarrier && CheckCancelFlag)
309  emitCancelationCheckImpl(Result, OMPD_parallel);
310 
311  return Builder.saveIP();
312 }
313 
316  Value *IfCondition,
317  omp::Directive CanceledDirective) {
318  if (!updateToLocation(Loc))
319  return Loc.IP;
320 
321  // LLVM utilities like blocks with terminators.
322  auto *UI = Builder.CreateUnreachable();
323 
324  Instruction *ThenTI = UI, *ElseTI = nullptr;
325  if (IfCondition)
326  SplitBlockAndInsertIfThenElse(IfCondition, UI, &ThenTI, &ElseTI);
327  Builder.SetInsertPoint(ThenTI);
328 
329  Value *CancelKind = nullptr;
330  switch (CanceledDirective) {
331 #define OMP_CANCEL_KIND(Enum, Str, DirectiveEnum, Value) \
332  case DirectiveEnum: \
333  CancelKind = Builder.getInt32(Value); \
334  break;
335 #include "llvm/Frontend/OpenMP/OMPKinds.def"
336  default:
337  llvm_unreachable("Unknown cancel kind!");
338  }
339 
340  Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
341  Value *Ident = getOrCreateIdent(SrcLocStr);
342  Value *Args[] = {Ident, getOrCreateThreadID(Ident), CancelKind};
343  Value *Result = Builder.CreateCall(
344  getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_cancel), Args);
345 
346  // The actual cancel logic is shared with others, e.g., cancel_barriers.
347  emitCancelationCheckImpl(Result, CanceledDirective);
348 
349  // Update the insertion point and remove the terminator we introduced.
350  Builder.SetInsertPoint(UI->getParent());
351  UI->eraseFromParent();
352 
353  return Builder.saveIP();
354 }
355 
357  Value *CancelFlag, omp::Directive CanceledDirective) {
358  assert(isLastFinalizationInfoCancellable(CanceledDirective) &&
359  "Unexpected cancellation!");
360 
361  // For a cancel barrier we create two new blocks.
362  BasicBlock *BB = Builder.GetInsertBlock();
363  BasicBlock *NonCancellationBlock;
364  if (Builder.GetInsertPoint() == BB->end()) {
365  // TODO: This branch will not be needed once we moved to the
366  // OpenMPIRBuilder codegen completely.
367  NonCancellationBlock = BasicBlock::Create(
368  BB->getContext(), BB->getName() + ".cont", BB->getParent());
369  } else {
370  NonCancellationBlock = SplitBlock(BB, &*Builder.GetInsertPoint());
372  Builder.SetInsertPoint(BB);
373  }
374  BasicBlock *CancellationBlock = BasicBlock::Create(
375  BB->getContext(), BB->getName() + ".cncl", BB->getParent());
376 
377  // Jump to them based on the return value.
378  Value *Cmp = Builder.CreateIsNull(CancelFlag);
379  Builder.CreateCondBr(Cmp, NonCancellationBlock, CancellationBlock,
380  /* TODO weight */ nullptr, nullptr);
381 
382  // From the cancellation block we finalize all variables and go to the
383  // post finalization block that is known to the FiniCB callback.
384  Builder.SetInsertPoint(CancellationBlock);
385  auto &FI = FinalizationStack.back();
386  FI.FiniCB(Builder.saveIP());
387 
388  // The continuation block is where code generation continues.
389  Builder.SetInsertPoint(NonCancellationBlock, NonCancellationBlock->begin());
390 }
391 
393  const LocationDescription &Loc, BodyGenCallbackTy BodyGenCB,
394  PrivatizeCallbackTy PrivCB, FinalizeCallbackTy FiniCB, Value *IfCondition,
395  Value *NumThreads, omp::ProcBindKind ProcBind, bool IsCancellable) {
396  if (!updateToLocation(Loc))
397  return Loc.IP;
398 
399  Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
400  Value *Ident = getOrCreateIdent(SrcLocStr);
401  Value *ThreadID = getOrCreateThreadID(Ident);
402 
403  if (NumThreads) {
404  // Build call __kmpc_push_num_threads(&Ident, global_tid, num_threads)
405  Value *Args[] = {
406  Ident, ThreadID,
407  Builder.CreateIntCast(NumThreads, Int32, /*isSigned*/ false)};
408  Builder.CreateCall(
409  getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_push_num_threads), Args);
410  }
411 
412  if (ProcBind != OMP_PROC_BIND_default) {
413  // Build call __kmpc_push_proc_bind(&Ident, global_tid, proc_bind)
414  Value *Args[] = {
415  Ident, ThreadID,
416  ConstantInt::get(Int32, unsigned(ProcBind), /*isSigned=*/true)};
417  Builder.CreateCall(
418  getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_push_proc_bind), Args);
419  }
420 
421  BasicBlock *InsertBB = Builder.GetInsertBlock();
422  Function *OuterFn = InsertBB->getParent();
423 
424  // Vector to remember instructions we used only during the modeling but which
425  // we want to delete at the end.
426  SmallVector<Instruction *, 4> ToBeDeleted;
427 
428  Builder.SetInsertPoint(OuterFn->getEntryBlock().getFirstNonPHI());
429  AllocaInst *TIDAddr = Builder.CreateAlloca(Int32, nullptr, "tid.addr");
430  AllocaInst *ZeroAddr = Builder.CreateAlloca(Int32, nullptr, "zero.addr");
431 
432  // If there is an if condition we actually use the TIDAddr and ZeroAddr in the
433  // program, otherwise we only need them for modeling purposes to get the
434  // associated arguments in the outlined function. In the former case,
435  // initialize the allocas properly, in the latter case, delete them later.
436  if (IfCondition) {
437  Builder.CreateStore(Constant::getNullValue(Int32), TIDAddr);
438  Builder.CreateStore(Constant::getNullValue(Int32), ZeroAddr);
439  } else {
440  ToBeDeleted.push_back(TIDAddr);
441  ToBeDeleted.push_back(ZeroAddr);
442  }
443 
444  // Create an artificial insertion point that will also ensure the blocks we
445  // are about to split are not degenerated.
446  auto *UI = new UnreachableInst(Builder.getContext(), InsertBB);
447 
448  Instruction *ThenTI = UI, *ElseTI = nullptr;
449  if (IfCondition)
450  SplitBlockAndInsertIfThenElse(IfCondition, UI, &ThenTI, &ElseTI);
451 
452  BasicBlock *ThenBB = ThenTI->getParent();
453  BasicBlock *PRegEntryBB = ThenBB->splitBasicBlock(ThenTI, "omp.par.entry");
454  BasicBlock *PRegBodyBB =
455  PRegEntryBB->splitBasicBlock(ThenTI, "omp.par.region");
456  BasicBlock *PRegPreFiniBB =
457  PRegBodyBB->splitBasicBlock(ThenTI, "omp.par.pre_finalize");
458  BasicBlock *PRegExitBB =
459  PRegPreFiniBB->splitBasicBlock(ThenTI, "omp.par.exit");
460 
461  auto FiniCBWrapper = [&](InsertPointTy IP) {
462  // Hide "open-ended" blocks from the given FiniCB by setting the right jump
463  // target to the region exit block.
464  if (IP.getBlock()->end() == IP.getPoint()) {
466  Builder.restoreIP(IP);
467  Instruction *I = Builder.CreateBr(PRegExitBB);
468  IP = InsertPointTy(I->getParent(), I->getIterator());
469  }
470  assert(IP.getBlock()->getTerminator()->getNumSuccessors() == 1 &&
471  IP.getBlock()->getTerminator()->getSuccessor(0) == PRegExitBB &&
472  "Unexpected insertion point for finalization call!");
473  return FiniCB(IP);
474  };
475 
476  FinalizationStack.push_back({FiniCBWrapper, OMPD_parallel, IsCancellable});
477 
478  // Generate the privatization allocas in the block that will become the entry
479  // of the outlined function.
480  InsertPointTy AllocaIP(PRegEntryBB,
481  PRegEntryBB->getTerminator()->getIterator());
482  Builder.restoreIP(AllocaIP);
483  AllocaInst *PrivTIDAddr =
484  Builder.CreateAlloca(Int32, nullptr, "tid.addr.local");
485  Instruction *PrivTID = Builder.CreateLoad(PrivTIDAddr, "tid");
486 
487  // Add some fake uses for OpenMP provided arguments.
488  ToBeDeleted.push_back(Builder.CreateLoad(TIDAddr, "tid.addr.use"));
489  ToBeDeleted.push_back(Builder.CreateLoad(ZeroAddr, "zero.addr.use"));
490 
491  // ThenBB
492  // |
493  // V
494  // PRegionEntryBB <- Privatization allocas are placed here.
495  // |
496  // V
497  // PRegionBodyBB <- BodeGen is invoked here.
498  // |
499  // V
500  // PRegPreFiniBB <- The block we will start finalization from.
501  // |
502  // V
503  // PRegionExitBB <- A common exit to simplify block collection.
504  //
505 
506  LLVM_DEBUG(dbgs() << "Before body codegen: " << *OuterFn << "\n");
507 
508  // Let the caller create the body.
509  assert(BodyGenCB && "Expected body generation callback!");
510  InsertPointTy CodeGenIP(PRegBodyBB, PRegBodyBB->begin());
511  BodyGenCB(AllocaIP, CodeGenIP, *PRegPreFiniBB);
512 
513  LLVM_DEBUG(dbgs() << "After body codegen: " << *OuterFn << "\n");
514 
515  FunctionCallee RTLFn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_fork_call);
516  if (auto *F = dyn_cast<llvm::Function>(RTLFn.getCallee())) {
517  if (!F->hasMetadata(llvm::LLVMContext::MD_callback)) {
518  llvm::LLVMContext &Ctx = F->getContext();
519  MDBuilder MDB(Ctx);
520  // Annotate the callback behavior of the __kmpc_fork_call:
521  // - The callback callee is argument number 2 (microtask).
522  // - The first two arguments of the callback callee are unknown (-1).
523  // - All variadic arguments to the __kmpc_fork_call are passed to the
524  // callback callee.
525  F->addMetadata(
526  llvm::LLVMContext::MD_callback,
528  Ctx, {MDB.createCallbackEncoding(2, {-1, -1},
529  /* VarArgsArePassed */ true)}));
530  }
531  }
532 
533  OutlineInfo OI;
534  OI.PostOutlineCB = [=](Function &OutlinedFn) {
535  // Add some known attributes.
536  OutlinedFn.addParamAttr(0, Attribute::NoAlias);
537  OutlinedFn.addParamAttr(1, Attribute::NoAlias);
538  OutlinedFn.addFnAttr(Attribute::NoUnwind);
539  OutlinedFn.addFnAttr(Attribute::NoRecurse);
540 
541  assert(OutlinedFn.arg_size() >= 2 &&
542  "Expected at least tid and bounded tid as arguments");
543  unsigned NumCapturedVars =
544  OutlinedFn.arg_size() - /* tid & bounded tid */ 2;
545 
546  CallInst *CI = cast<CallInst>(OutlinedFn.user_back());
547  CI->getParent()->setName("omp_parallel");
548  Builder.SetInsertPoint(CI);
549 
550  // Build call __kmpc_fork_call(Ident, n, microtask, var1, .., varn);
551  Value *ForkCallArgs[] = {
552  Ident, Builder.getInt32(NumCapturedVars),
553  Builder.CreateBitCast(&OutlinedFn, ParallelTaskPtr)};
554 
555  SmallVector<Value *, 16> RealArgs;
556  RealArgs.append(std::begin(ForkCallArgs), std::end(ForkCallArgs));
557  RealArgs.append(CI->arg_begin() + /* tid & bound tid */ 2, CI->arg_end());
558 
559  Builder.CreateCall(RTLFn, RealArgs);
560 
561  LLVM_DEBUG(dbgs() << "With fork_call placed: "
562  << *Builder.GetInsertBlock()->getParent() << "\n");
563 
564  InsertPointTy ExitIP(PRegExitBB, PRegExitBB->end());
565 
566  // Initialize the local TID stack location with the argument value.
567  Builder.SetInsertPoint(PrivTID);
568  Function::arg_iterator OutlinedAI = OutlinedFn.arg_begin();
569  Builder.CreateStore(Builder.CreateLoad(OutlinedAI), PrivTIDAddr);
570 
571  // If no "if" clause was present we do not need the call created during
572  // outlining, otherwise we reuse it in the serialized parallel region.
573  if (!ElseTI) {
574  CI->eraseFromParent();
575  } else {
576 
577  // If an "if" clause was present we are now generating the serialized
578  // version into the "else" branch.
579  Builder.SetInsertPoint(ElseTI);
580 
581  // Build calls __kmpc_serialized_parallel(&Ident, GTid);
582  Value *SerializedParallelCallArgs[] = {Ident, ThreadID};
583  Builder.CreateCall(
584  getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_serialized_parallel),
585  SerializedParallelCallArgs);
586 
587  // OutlinedFn(&GTid, &zero, CapturedStruct);
588  CI->removeFromParent();
589  Builder.Insert(CI);
590 
591  // __kmpc_end_serialized_parallel(&Ident, GTid);
592  Value *EndArgs[] = {Ident, ThreadID};
593  Builder.CreateCall(
594  getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_end_serialized_parallel),
595  EndArgs);
596 
597  LLVM_DEBUG(dbgs() << "With serialized parallel region: "
598  << *Builder.GetInsertBlock()->getParent() << "\n");
599  }
600 
601  for (Instruction *I : ToBeDeleted)
602  I->eraseFromParent();
603  };
604 
605  // Adjust the finalization stack, verify the adjustment, and call the
606  // finalize function a last time to finalize values between the pre-fini
607  // block and the exit block if we left the parallel "the normal way".
608  auto FiniInfo = FinalizationStack.pop_back_val();
609  (void)FiniInfo;
610  assert(FiniInfo.DK == OMPD_parallel &&
611  "Unexpected finalization stack state!");
612 
613  Instruction *PRegPreFiniTI = PRegPreFiniBB->getTerminator();
614 
615  InsertPointTy PreFiniIP(PRegPreFiniBB, PRegPreFiniTI->getIterator());
616  FiniCB(PreFiniIP);
617 
618  SmallPtrSet<BasicBlock *, 32> ParallelRegionBlockSet;
620  ParallelRegionBlockSet.insert(PRegEntryBB);
621  ParallelRegionBlockSet.insert(PRegExitBB);
622 
623  // Collect all blocks in-between PRegEntryBB and PRegExitBB.
624  Worklist.push_back(PRegEntryBB);
625  while (!Worklist.empty()) {
626  BasicBlock *BB = Worklist.pop_back_val();
627  OI.Blocks.push_back(BB);
628  for (BasicBlock *SuccBB : successors(BB))
629  if (ParallelRegionBlockSet.insert(SuccBB).second)
630  Worklist.push_back(SuccBB);
631  }
632 
633  // Ensure a single exit node for the outlined region by creating one.
634  // We might have multiple incoming edges to the exit now due to finalizations,
635  // e.g., cancel calls that cause the control flow to leave the region.
636  BasicBlock *PRegOutlinedExitBB = PRegExitBB;
637  PRegExitBB = SplitBlock(PRegExitBB, &*PRegExitBB->getFirstInsertionPt());
638  PRegOutlinedExitBB->setName("omp.par.outlined.exit");
639  OI.Blocks.push_back(PRegOutlinedExitBB);
640 
641  CodeExtractorAnalysisCache CEAC(*OuterFn);
642  CodeExtractor Extractor(OI.Blocks, /* DominatorTree */ nullptr,
643  /* AggregateArgs */ false,
644  /* BlockFrequencyInfo */ nullptr,
645  /* BranchProbabilityInfo */ nullptr,
646  /* AssumptionCache */ nullptr,
647  /* AllowVarArgs */ true,
648  /* AllowAlloca */ true,
649  /* Suffix */ ".omp_par");
650 
651  // Find inputs to, outputs from the code region.
652  BasicBlock *CommonExit = nullptr;
653  SetVector<Value *> Inputs, Outputs, SinkingCands, HoistingCands;
654  Extractor.findAllocas(CEAC, SinkingCands, HoistingCands, CommonExit);
655  Extractor.findInputsOutputs(Inputs, Outputs, SinkingCands);
656 
657  LLVM_DEBUG(dbgs() << "Before privatization: " << *OuterFn << "\n");
658 
659  FunctionCallee TIDRTLFn =
660  getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_global_thread_num);
661 
662  auto PrivHelper = [&](Value &V) {
663  if (&V == TIDAddr || &V == ZeroAddr)
664  return;
665 
667  for (Use &U : V.uses())
668  if (auto *UserI = dyn_cast<Instruction>(U.getUser()))
669  if (ParallelRegionBlockSet.count(UserI->getParent()))
670  Uses.push_back(&U);
671 
672  Value *ReplacementValue = nullptr;
673  CallInst *CI = dyn_cast<CallInst>(&V);
674  if (CI && CI->getCalledFunction() == TIDRTLFn.getCallee()) {
675  ReplacementValue = PrivTID;
676  } else {
677  Builder.restoreIP(
678  PrivCB(AllocaIP, Builder.saveIP(), V, ReplacementValue));
679  assert(ReplacementValue &&
680  "Expected copy/create callback to set replacement value!");
681  if (ReplacementValue == &V)
682  return;
683  }
684 
685  for (Use *UPtr : Uses)
686  UPtr->set(ReplacementValue);
687  };
688 
689  for (Value *Input : Inputs) {
690  LLVM_DEBUG(dbgs() << "Captured input: " << *Input << "\n");
691  PrivHelper(*Input);
692  }
693  assert(Outputs.empty() &&
694  "OpenMP outlining should not produce live-out values!");
695 
696  LLVM_DEBUG(dbgs() << "After privatization: " << *OuterFn << "\n");
697  LLVM_DEBUG({
698  for (auto *BB : OI.Blocks)
699  dbgs() << " PBR: " << BB->getName() << "\n";
700  });
701 
702  // Register the outlined info.
703  addOutlineInfo(std::move(OI));
704 
705  InsertPointTy AfterIP(UI->getParent(), UI->getParent()->end());
706  UI->eraseFromParent();
707 
708  return AfterIP;
709 }
710 
712  // Build call void __kmpc_flush(ident_t *loc)
713  Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
714  Value *Args[] = {getOrCreateIdent(SrcLocStr)};
715 
716  Builder.CreateCall(getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_flush), Args);
717 }
718 
720  if (!updateToLocation(Loc))
721  return;
722  emitFlush(Loc);
723 }
724 
726  // Build call kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32
727  // global_tid);
728  Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
729  Value *Ident = getOrCreateIdent(SrcLocStr);
730  Value *Args[] = {Ident, getOrCreateThreadID(Ident)};
731 
732  // Ignore return result until untied tasks are supported.
733  Builder.CreateCall(getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_omp_taskwait),
734  Args);
735 }
736 
738  if (!updateToLocation(Loc))
739  return;
740  emitTaskwaitImpl(Loc);
741 }
742 
744  // Build call __kmpc_omp_taskyield(loc, thread_id, 0);
745  Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
746  Value *Ident = getOrCreateIdent(SrcLocStr);
747  Constant *I32Null = ConstantInt::getNullValue(Int32);
748  Value *Args[] = {Ident, getOrCreateThreadID(Ident), I32Null};
749 
750  Builder.CreateCall(getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_omp_taskyield),
751  Args);
752 }
753 
755  if (!updateToLocation(Loc))
756  return;
757  emitTaskyieldImpl(Loc);
758 }
759 
762  BodyGenCallbackTy BodyGenCB,
763  FinalizeCallbackTy FiniCB) {
764 
765  if (!updateToLocation(Loc))
766  return Loc.IP;
767 
768  Directive OMPD = Directive::OMPD_master;
769  Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
770  Value *Ident = getOrCreateIdent(SrcLocStr);
771  Value *ThreadId = getOrCreateThreadID(Ident);
772  Value *Args[] = {Ident, ThreadId};
773 
774  Function *EntryRTLFn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_master);
775  Instruction *EntryCall = Builder.CreateCall(EntryRTLFn, Args);
776 
777  Function *ExitRTLFn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_end_master);
778  Instruction *ExitCall = Builder.CreateCall(ExitRTLFn, Args);
779 
780  return EmitOMPInlinedRegion(OMPD, EntryCall, ExitCall, BodyGenCB, FiniCB,
781  /*Conditional*/ true, /*hasFinalize*/ true);
782 }
783 
785  const LocationDescription &Loc, BodyGenCallbackTy BodyGenCB,
786  FinalizeCallbackTy FiniCB, StringRef CriticalName, Value *HintInst) {
787 
788  if (!updateToLocation(Loc))
789  return Loc.IP;
790 
791  Directive OMPD = Directive::OMPD_critical;
792  Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
793  Value *Ident = getOrCreateIdent(SrcLocStr);
794  Value *ThreadId = getOrCreateThreadID(Ident);
795  Value *LockVar = getOMPCriticalRegionLock(CriticalName);
796  Value *Args[] = {Ident, ThreadId, LockVar};
797 
798  SmallVector<llvm::Value *, 4> EnterArgs(std::begin(Args), std::end(Args));
799  Function *RTFn = nullptr;
800  if (HintInst) {
801  // Add Hint to entry Args and create call
802  EnterArgs.push_back(HintInst);
803  RTFn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_critical_with_hint);
804  } else {
805  RTFn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_critical);
806  }
807  Instruction *EntryCall = Builder.CreateCall(RTFn, EnterArgs);
808 
809  Function *ExitRTLFn =
810  getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_end_critical);
811  Instruction *ExitCall = Builder.CreateCall(ExitRTLFn, Args);
812 
813  return EmitOMPInlinedRegion(OMPD, EntryCall, ExitCall, BodyGenCB, FiniCB,
814  /*Conditional*/ false, /*hasFinalize*/ true);
815 }
816 
817 OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::EmitOMPInlinedRegion(
818  Directive OMPD, Instruction *EntryCall, Instruction *ExitCall,
819  BodyGenCallbackTy BodyGenCB, FinalizeCallbackTy FiniCB, bool Conditional,
820  bool HasFinalize) {
821 
822  if (HasFinalize)
823  FinalizationStack.push_back({FiniCB, OMPD, /*IsCancellable*/ false});
824 
825  // Create inlined region's entry and body blocks, in preparation
826  // for conditional creation
827  BasicBlock *EntryBB = Builder.GetInsertBlock();
828  Instruction *SplitPos = EntryBB->getTerminator();
829  if (!isa_and_nonnull<BranchInst>(SplitPos))
830  SplitPos = new UnreachableInst(Builder.getContext(), EntryBB);
831  BasicBlock *ExitBB = EntryBB->splitBasicBlock(SplitPos, "omp_region.end");
832  BasicBlock *FiniBB =
833  EntryBB->splitBasicBlock(EntryBB->getTerminator(), "omp_region.finalize");
834 
835  Builder.SetInsertPoint(EntryBB->getTerminator());
836  emitCommonDirectiveEntry(OMPD, EntryCall, ExitBB, Conditional);
837 
838  // generate body
839  BodyGenCB(/* AllocaIP */ InsertPointTy(),
840  /* CodeGenIP */ Builder.saveIP(), *FiniBB);
841 
842  // If we didn't emit a branch to FiniBB during body generation, it means
843  // FiniBB is unreachable (e.g. while(1);). stop generating all the
844  // unreachable blocks, and remove anything we are not going to use.
845  auto SkipEmittingRegion = FiniBB->hasNPredecessors(0);
846  if (SkipEmittingRegion) {
847  FiniBB->eraseFromParent();
848  ExitCall->eraseFromParent();
849  // Discard finalization if we have it.
850  if (HasFinalize) {
851  assert(!FinalizationStack.empty() &&
852  "Unexpected finalization stack state!");
853  FinalizationStack.pop_back();
854  }
855  } else {
856  // emit exit call and do any needed finalization.
857  auto FinIP = InsertPointTy(FiniBB, FiniBB->getFirstInsertionPt());
858  assert(FiniBB->getTerminator()->getNumSuccessors() == 1 &&
859  FiniBB->getTerminator()->getSuccessor(0) == ExitBB &&
860  "Unexpected control flow graph state!!");
861  emitCommonDirectiveExit(OMPD, FinIP, ExitCall, HasFinalize);
862  assert(FiniBB->getUniquePredecessor()->getUniqueSuccessor() == FiniBB &&
863  "Unexpected Control Flow State!");
865  }
866 
867  // If we are skipping the region of a non conditional, remove the exit
868  // block, and clear the builder's insertion point.
869  assert(SplitPos->getParent() == ExitBB &&
870  "Unexpected Insertion point location!");
871  if (!Conditional && SkipEmittingRegion) {
872  ExitBB->eraseFromParent();
873  Builder.ClearInsertionPoint();
874  } else {
875  auto merged = MergeBlockIntoPredecessor(ExitBB);
876  BasicBlock *ExitPredBB = SplitPos->getParent();
877  auto InsertBB = merged ? ExitPredBB : ExitBB;
878  if (!isa_and_nonnull<BranchInst>(SplitPos))
879  SplitPos->eraseFromParent();
880  Builder.SetInsertPoint(InsertBB);
881  }
882 
883  return Builder.saveIP();
884 }
885 
886 OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::emitCommonDirectiveEntry(
887  Directive OMPD, Value *EntryCall, BasicBlock *ExitBB, bool Conditional) {
888 
889  // if nothing to do, Return current insertion point.
890  if (!Conditional)
891  return Builder.saveIP();
892 
893  BasicBlock *EntryBB = Builder.GetInsertBlock();
894  Value *CallBool = Builder.CreateIsNotNull(EntryCall);
895  auto *ThenBB = BasicBlock::Create(M.getContext(), "omp_region.body");
896  auto *UI = new UnreachableInst(Builder.getContext(), ThenBB);
897 
898  // Emit thenBB and set the Builder's insertion point there for
899  // body generation next. Place the block after the current block.
900  Function *CurFn = EntryBB->getParent();
901  CurFn->getBasicBlockList().insertAfter(EntryBB->getIterator(), ThenBB);
902 
903  // Move Entry branch to end of ThenBB, and replace with conditional
904  // branch (If-stmt)
905  Instruction *EntryBBTI = EntryBB->getTerminator();
906  Builder.CreateCondBr(CallBool, ThenBB, ExitBB);
907  EntryBBTI->removeFromParent();
908  Builder.SetInsertPoint(UI);
909  Builder.Insert(EntryBBTI);
910  UI->eraseFromParent();
911  Builder.SetInsertPoint(ThenBB->getTerminator());
912 
913  // return an insertion point to ExitBB.
914  return IRBuilder<>::InsertPoint(ExitBB, ExitBB->getFirstInsertionPt());
915 }
916 
917 OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::emitCommonDirectiveExit(
918  omp::Directive OMPD, InsertPointTy FinIP, Instruction *ExitCall,
919  bool HasFinalize) {
920 
921  Builder.restoreIP(FinIP);
922 
923  // If there is finalization to do, emit it before the exit call
924  if (HasFinalize) {
925  assert(!FinalizationStack.empty() &&
926  "Unexpected finalization stack state!");
927 
928  FinalizationInfo Fi = FinalizationStack.pop_back_val();
929  assert(Fi.DK == OMPD && "Unexpected Directive for Finalization call!");
930 
931  Fi.FiniCB(FinIP);
932 
933  BasicBlock *FiniBB = FinIP.getBlock();
934  Instruction *FiniBBTI = FiniBB->getTerminator();
935 
936  // set Builder IP for call creation
937  Builder.SetInsertPoint(FiniBBTI);
938  }
939 
940  // place the Exitcall as last instruction before Finalization block terminator
941  ExitCall->removeFromParent();
942  Builder.Insert(ExitCall);
943 
944  return IRBuilder<>::InsertPoint(ExitCall->getParent(),
945  ExitCall->getIterator());
946 }
947 
949  InsertPointTy IP, Value *MasterAddr, Value *PrivateAddr,
950  llvm::IntegerType *IntPtrTy, bool BranchtoEnd) {
951  if (!IP.isSet())
952  return IP;
953 
955 
956  // creates the following CFG structure
957  // OMP_Entry : (MasterAddr != PrivateAddr)?
958  // F T
959  // | \
960  // | copin.not.master
961  // | /
962  // v /
963  // copyin.not.master.end
964  // |
965  // v
966  // OMP.Entry.Next
967 
968  BasicBlock *OMP_Entry = IP.getBlock();
969  Function *CurFn = OMP_Entry->getParent();
970  BasicBlock *CopyBegin =
971  BasicBlock::Create(M.getContext(), "copyin.not.master", CurFn);
972  BasicBlock *CopyEnd = nullptr;
973 
974  // If entry block is terminated, split to preserve the branch to following
975  // basic block (i.e. OMP.Entry.Next), otherwise, leave everything as is.
976  if (isa_and_nonnull<BranchInst>(OMP_Entry->getTerminator())) {
977  CopyEnd = OMP_Entry->splitBasicBlock(OMP_Entry->getTerminator(),
978  "copyin.not.master.end");
979  OMP_Entry->getTerminator()->eraseFromParent();
980  } else {
981  CopyEnd =
982  BasicBlock::Create(M.getContext(), "copyin.not.master.end", CurFn);
983  }
984 
985  Builder.SetInsertPoint(OMP_Entry);
986  Value *MasterPtr = Builder.CreatePtrToInt(MasterAddr, IntPtrTy);
987  Value *PrivatePtr = Builder.CreatePtrToInt(PrivateAddr, IntPtrTy);
988  Value *cmp = Builder.CreateICmpNE(MasterPtr, PrivatePtr);
989  Builder.CreateCondBr(cmp, CopyBegin, CopyEnd);
990 
991  Builder.SetInsertPoint(CopyBegin);
992  if (BranchtoEnd)
993  Builder.SetInsertPoint(Builder.CreateBr(CopyEnd));
994 
995  return Builder.saveIP();
996 }
997 
1000  std::string Name) {
1002  Builder.restoreIP(Loc.IP);
1003 
1004  Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
1005  Value *Ident = getOrCreateIdent(SrcLocStr);
1006  Value *ThreadId = getOrCreateThreadID(Ident);
1007  Value *Args[] = {ThreadId, Size, Allocator};
1008 
1009  Function *Fn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_alloc);
1010 
1011  return Builder.CreateCall(Fn, Args, Name);
1012 }
1013 
1015  Value *Addr, Value *Allocator,
1016  std::string Name) {
1018  Builder.restoreIP(Loc.IP);
1019 
1020  Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
1021  Value *Ident = getOrCreateIdent(SrcLocStr);
1022  Value *ThreadId = getOrCreateThreadID(Ident);
1023  Value *Args[] = {ThreadId, Addr, Allocator};
1024  Function *Fn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_free);
1025  return Builder.CreateCall(Fn, Args, Name);
1026 }
1027 
1029  const LocationDescription &Loc, llvm::Value *Pointer,
1032  Builder.restoreIP(Loc.IP);
1033 
1034  Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
1035  Value *Ident = getOrCreateIdent(SrcLocStr);
1036  Value *ThreadId = getOrCreateThreadID(Ident);
1037  Constant *ThreadPrivateCache =
1038  getOrCreateOMPInternalVariable(Int8PtrPtr, Name);
1039  llvm::Value *Args[] = {Ident, ThreadId, Pointer, Size, ThreadPrivateCache};
1040 
1041  Function *Fn =
1042  getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_threadprivate_cached);
1043 
1044  return Builder.CreateCall(Fn, Args);
1045 }
1046 
1047 std::string OpenMPIRBuilder::getNameWithSeparators(ArrayRef<StringRef> Parts,
1048  StringRef FirstSeparator,
1049  StringRef Separator) {
1050  SmallString<128> Buffer;
1051  llvm::raw_svector_ostream OS(Buffer);
1052  StringRef Sep = FirstSeparator;
1053  for (StringRef Part : Parts) {
1054  OS << Sep << Part;
1055  Sep = Separator;
1056  }
1057  return OS.str().str();
1058 }
1059 
1060 Constant *OpenMPIRBuilder::getOrCreateOMPInternalVariable(
1061  llvm::Type *Ty, const llvm::Twine &Name, unsigned AddressSpace) {
1062  // TODO: Replace the twine arg with stringref to get rid of the conversion
1063  // logic. However This is taken from current implementation in clang as is.
1064  // Since this method is used in many places exclusively for OMP internal use
1065  // we will keep it as is for temporarily until we move all users to the
1066  // builder and then, if possible, fix it everywhere in one go.
1067  SmallString<256> Buffer;
1068  llvm::raw_svector_ostream Out(Buffer);
1069  Out << Name;
1070  StringRef RuntimeName = Out.str();
1071  auto &Elem = *InternalVars.try_emplace(RuntimeName, nullptr).first;
1072  if (Elem.second) {
1073  assert(Elem.second->getType()->getPointerElementType() == Ty &&
1074  "OMP internal variable has different type than requested");
1075  } else {
1076  // TODO: investigate the appropriate linkage type used for the global
1077  // variable for possibly changing that to internal or private, or maybe
1078  // create different versions of the function for different OMP internal
1079  // variables.
1080  Elem.second = new llvm::GlobalVariable(
1081  M, Ty, /*IsConstant*/ false, llvm::GlobalValue::CommonLinkage,
1082  llvm::Constant::getNullValue(Ty), Elem.first(),
1083  /*InsertBefore=*/nullptr, llvm::GlobalValue::NotThreadLocal,
1084  AddressSpace);
1085  }
1086 
1087  return Elem.second;
1088 }
1089 
1090 Value *OpenMPIRBuilder::getOMPCriticalRegionLock(StringRef CriticalName) {
1091  std::string Prefix = Twine("gomp_critical_user_", CriticalName).str();
1092  std::string Name = getNameWithSeparators({Prefix, "var"}, ".", ".");
1093  return getOrCreateOMPInternalVariable(KmpCriticalNameTy, Name);
1094 }
uint64_t CallInst * C
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks &#39;this&#39; from the containing basic block and deletes it.
Definition: Instruction.cpp:80
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:233
Utility class for extracting code into a new function.
Definition: CodeExtractor.h:85
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
InsertPointTy CreateCritical(const LocationDescription &Loc, BodyGenCallbackTy BodyGenCB, FinalizeCallbackTy FiniCB, StringRef CriticalName, Value *HintInst)
Generator for &#39;#omp critical&#39;.
static Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true)
This method constructs a CDS and initializes it with a text string.
Definition: Constants.cpp:2800
LLVM_NODISCARD std::enable_if_t< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast(const Y &Val)
Definition: Casting.h:334
bool hasNPredecessors(unsigned N) const
Return true if this block has exactly N predecessors.
Definition: BasicBlock.cpp:285
RuntimeFunction
IDs for all omp runtime library (RTL) functions.
Definition: OMPConstants.h:53
DILocation * get() const
Get the underlying DILocation.
Definition: DebugLoc.cpp:21
This class represents an incoming formal argument to a Function.
Definition: Argument.h:29
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:248
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:224
CallInst * CreateOMPFree(const LocationDescription &Loc, Value *Addr, Value *Allocator, std::string Name="")
Create a runtime call for kmpc_free.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:67
void findInputsOutputs(ValueSet &Inputs, ValueSet &Outputs, const ValueSet &Allocas) const
Compute the set of input values and output values for the code.
BasicBlock * getSuccessor(unsigned Idx) const
Return the specified successor. This instruction must be a terminator.
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:170
InsertPointTy emitBarrierImpl(const LocationDescription &Loc, omp::Directive DK, bool ForceSimpleCall, bool CheckCancelFlag)
Generate a barrier runtime call.
This class represents a function call, abstracting a target machine&#39;s calling convention.
The two locations do not alias at all.
Definition: AliasAnalysis.h:83
void CreateTaskwait(const LocationDescription &Loc)
Generator for &#39;#omp taskwait&#39;.
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:176
Like Internal, but omit from symbol table.
Definition: GlobalValue.h:56
void emitFlush(const LocationDescription &Loc)
Generate a flush runtime call.
InsertPointTy CreateCopyinClauseBlocks(InsertPointTy IP, Value *MasterAddr, Value *PrivateAddr, llvm::IntegerType *IntPtrTy, bool BranchtoEnd=true)
Generate conditional branch and relevant BasicBlocks through which private threads copy the &#39;copyin&#39; ...
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:550
bool isEligible() const
Test whether this code extractor is eligible.
F(f)
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
Definition: InstrTypes.h:1215
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.cpp:150
BasicBlock * SplitBlock(BasicBlock *Old, Instruction *SplitPt, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the specified block at the specified instruction - everything before SplitPt stays in Old and e...
LLVMContext & getContext() const
Get the context in which this basic block lives.
Definition: BasicBlock.cpp:32
Tentative definitions.
Definition: GlobalValue.h:58
void findAllocas(const CodeExtractorAnalysisCache &CEAC, ValueSet &SinkCands, ValueSet &HoistCands, BasicBlock *&ExitBlock) const
Find the set of allocas whose life ranges are contained within the outlined region.
static Constant * getNullValue(Type *Ty)
Constructor to create a &#39;0&#39; constant of arbitrary type.
Definition: Constants.cpp:328
iterator begin()
Instruction iterator methods.
Definition: BasicBlock.h:289
bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, MemoryDependenceResults *MemDep=nullptr, bool PredecessorWithTwoSuccessors=false)
Attempts to merge a block into its predecessor, if possible.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
IRBuilder<>::InsertPoint InsertPointTy
Type used throughout for insertion points.
Definition: OMPIRBuilder.h:45
A Use represents the edge between a Value definition and its users.
Definition: Use.h:44
Constant * getOrCreateDefaultSrcLocStr()
Return the (LLVM-IR) string describing the default source location.
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
Definition: Type.cpp:681
Function * getOrCreateRuntimeFunctionPtr(omp::RuntimeFunction FnID)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2560
void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:342
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:156
void initializeTypes(Module &M)
Helper to initialize all types defined in OpenMP/OMPKinds.def.
Class to represent function types.
Definition: DerivedTypes.h:108
const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
Definition: BasicBlock.cpp:271
ProcBindKind
IDs for the different proc bind kinds.
Definition: OMPConstants.h:72
InsertPointTy CreateCancel(const LocationDescription &Loc, Value *IfCondition, omp::Directive CanceledDirective)
Generator for &#39;#omp cancel&#39;.
Value * getOrCreateThreadID(Value *Ident)
Return the current thread ID.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
Value * getOrCreateIdent(Constant *SrcLocStr, omp::IdentFlag Flags=omp::IdentFlag(0))
Return an ident_t* encoding the source location SrcLocStr and Flags.
Debug location.
CallInst * CreateCachedThreadPrivate(const LocationDescription &Loc, llvm::Value *Pointer, llvm::ConstantInt *Size, const llvm::Twine &Name=Twine(""))
Create a runtime call for kmpc_threadprivate_cached.
void emitTaskwaitImpl(const LocationDescription &Loc)
Generate a taskwait runtime call.
static void addAttributes(omp::RuntimeFunction FnID, Function &Fn)
Add attributes known for FnID to Fn.
unsigned getNumSuccessors() const
Return the number of successors that this instruction has.
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition: Constants.cpp:2004
const BasicBlock & getEntryBlock() const
Definition: Function.h:689
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata *> MDs)
Definition: Metadata.h:1172
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:434
const Instruction * getFirstNonPHI() const
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
Definition: BasicBlock.cpp:214
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
Definition: BasicBlock.cpp:241
static cl::opt< bool > OptimisticAttributes("openmp-ir-builder-optimistic-attributes", cl::Hidden, cl::desc("Use optimistic attributes describing " "'as-if' properties of runtime calls."), cl::init(false))
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
This function has undefined behavior.
This is an important base class in LLVM.
Definition: Constant.h:41
MDNode * createCallbackEncoding(unsigned CalleeArgNo, ArrayRef< int > Arguments, bool VarArgsArePassed)
Return metadata describing a callback (see llvm::AbstractCallSite).
Definition: MDBuilder.cpp:107
void emitTaskyieldImpl(const LocationDescription &Loc)
Generate a taskyield runtime call.
const Instruction & front() const
Definition: BasicBlock.h:301
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:364
void initialize()
Initialize the internal state, this will put structures types and potentially other helpers into the ...
A cache for the CodeExtractor analysis.
Definition: CodeExtractor.h:46
static Constant * get(StructType *T, ArrayRef< Constant *> V)
Definition: Constants.cpp:1219
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:100
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Definition: SmallPtrSet.h:375
self_iterator getIterator()
Definition: ilist_node.h:81
Class to represent integer types.
Definition: DerivedTypes.h:40
IRBuilder ::InsertPoint CreateParallel(const LocationDescription &Loc, BodyGenCallbackTy BodyGenCB, PrivatizeCallbackTy PrivCB, FinalizeCallbackTy FiniCB, Value *IfCondition, Value *NumThreads, omp::ProcBindKind ProcBind, bool IsCancellable)
Generator for &#39;#omp parallel&#39;.
CallInst * CreateOMPAlloc(const LocationDescription &Loc, Value *Size, Value *Allocator, std::string Name="")
Create a runtime call for kmpc_Alloc.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:230
assume Assume Builder
StringRef str() const
Return a StringRef for the vector contents.
Definition: raw_ostream.h:575
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
Definition: Constants.cpp:1816
Basic Register Allocator
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
Definition: SmallPtrSet.h:439
This is the shared class of boolean and integer constants.
Definition: Constants.h:77
iterator end()
Definition: BasicBlock.h:291
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:883
AddressSpace
Definition: NVPTXBaseInfo.h:21
Helper that contains information about regions we need to outline during finalization.
Definition: OMPIRBuilder.h:287
void addMetadata(unsigned KindID, MDNode &MD)
Add a metadata attachment.
Definition: Metadata.cpp:1393
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:420
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:786
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:165
static FunctionCallee getOrCreateRuntimeFunction(Module &M, omp::RuntimeFunction FnID)
Return the function declaration for the runtime function with FnID.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:433
Function * extractCodeRegion(const CodeExtractorAnalysisCache &CEAC)
Perform the extraction, returning the new function.
InsertPointTy CreateBarrier(const LocationDescription &Loc, omp::Directive DK, bool ForceSimpleCall=false, bool CheckCancelFlag=true)
Emitter methods for OpenMP directives.
void removeFromParent()
This method unlinks &#39;this&#39; from the containing basic block, but does not delete it.
Definition: Instruction.cpp:76
void SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore, Instruction **ThenTerm, Instruction **ElseTerm, MDNode *BranchWeights=nullptr)
SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen, but also creates the ElseBlock...
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
Definition: InstrTypes.h:1209
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
void setAlignment(MaybeAlign Align)
Definition: Globals.cpp:116
void setUnnamedAddr(UnnamedAddr Val)
Definition: GlobalValue.h:212
Description of a LLVM-IR insertion point (IP) and a debug/source location (filename, line, column, ...).
Definition: OMPIRBuilder.h:118
void CreateFlush(const LocationDescription &Loc)
Generator for &#39;#omp flush&#39;.
void finalize()
Finalize the underlying module, e.g., by outlining regions.
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:270
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
Definition: InstrTypes.h:1299
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:107
SymbolTableList< BasicBlock >::iterator eraseFromParent()
Unlink &#39;this&#39; from the containing function and delete it.
Definition: BasicBlock.cpp:127
#define I(x, y, z)
Definition: MD5.cpp:59
bool empty() const
Determine if the SetVector is empty or not.
Definition: SetVector.h:72
const BasicBlockListType & getBasicBlockList() const
Get the underlying elements of the Function...
Definition: Function.h:682
uint32_t Size
Definition: Profile.cpp:46
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
Definition: BasicBlock.cpp:392
std::string str() const
Return the twine contents as a std::string.
Definition: Twine.cpp:17
const std::string to_string(const T &Value)
Definition: ScopedPrinter.h:61
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:152
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::function< void(InsertPointTy CodeGenIP)> FinalizeCallbackTy
Callback type for variable finalization (think destructors).
Definition: OMPIRBuilder.h:55
SmallVector< BasicBlock *, 32 > Blocks
Definition: OMPIRBuilder.h:288
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:572
LLVM Value Representation.
Definition: Value.h:74
void CreateTaskyield(const LocationDescription &Loc)
Generator for &#39;#omp taskyield&#39;.
InsertPointTy CreateMaster(const LocationDescription &Loc, BodyGenCallbackTy BodyGenCB, FinalizeCallbackTy FiniCB)
Generator for &#39;#omp master&#39;.
bool hasMetadata() const
Check if this has any metadata.
Definition: GlobalObject.h:131
succ_range successors(Instruction *I)
Definition: CFG.h:260
void emitCancelationCheckImpl(Value *CancelFlag, omp::Directive CanceledDirective)
Generate control flow and cleanup for cancellation.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
Constant * getOrCreateSrcLocStr(StringRef LocStr)
Return the (LLVM-IR) string describing the source location LocStr.
#define LLVM_DEBUG(X)
Definition: Debug.h:122
iterator insertAfter(iterator where, pointer New)
Definition: ilist.h:237
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
const BasicBlock * getParent() const
Definition: Instruction.h:85
IdentFlag
IDs for all omp runtime library ident_t flag encodings (see their defintion in openmp/runtime/src/kmp...
Definition: OMPConstants.h:83
an instruction to allocate memory on the stack
Definition: Instructions.h:60
const BasicBlock * getUniqueSuccessor() const
Return the successor of this block if it has a unique successor.
Definition: BasicBlock.cpp:301