23 #include "llvm/ADT/StringExtras.h"
24 #include "llvm/IR/CallSite.h"
25 #include "llvm/IR/DataLayout.h"
26 #include "llvm/IR/InlineAsm.h"
27 #include "llvm/IR/Intrinsics.h"
28 using namespace clang;
29 using namespace CodeGen;
38 Loc = S->getLocStart();
46 assert(S &&
"Null statement?");
63 assert(!isa<DeclStmt>(*S) &&
"Unexpected DeclStmt!");
74 switch (S->getStmtClass()) {
75 case Stmt::NoStmtClass:
76 case Stmt::CXXCatchStmtClass:
77 case Stmt::SEHExceptStmtClass:
78 case Stmt::SEHFinallyStmtClass:
79 case Stmt::MSDependentExistsStmtClass:
80 llvm_unreachable(
"invalid statement class to emit generically");
81 case Stmt::NullStmtClass:
82 case Stmt::CompoundStmtClass:
83 case Stmt::DeclStmtClass:
84 case Stmt::LabelStmtClass:
85 case Stmt::AttributedStmtClass:
86 case Stmt::GotoStmtClass:
87 case Stmt::BreakStmtClass:
88 case Stmt::ContinueStmtClass:
89 case Stmt::DefaultStmtClass:
90 case Stmt::CaseStmtClass:
91 case Stmt::SEHLeaveStmtClass:
92 llvm_unreachable(
"should have emitted these statements as simple");
94 #define STMT(Type, Base)
95 #define ABSTRACT_STMT(Op)
96 #define EXPR(Type, Base) \
97 case Stmt::Type##Class:
98 #include "clang/AST/StmtNodes.inc"
101 llvm::BasicBlock *incoming =
Builder.GetInsertBlock();
102 assert(incoming &&
"expression emission must have an insertion point");
106 llvm::BasicBlock *outgoing =
Builder.GetInsertBlock();
107 assert(outgoing &&
"expression emission cleared block!");
121 if (incoming != outgoing && outgoing->use_empty()) {
122 outgoing->eraseFromParent();
128 case Stmt::IndirectGotoStmtClass:
131 case Stmt::IfStmtClass:
EmitIfStmt(cast<IfStmt>(*S));
break;
132 case Stmt::WhileStmtClass:
EmitWhileStmt(cast<WhileStmt>(*S));
break;
133 case Stmt::DoStmtClass:
EmitDoStmt(cast<DoStmt>(*S));
break;
134 case Stmt::ForStmtClass:
EmitForStmt(cast<ForStmt>(*S));
break;
136 case Stmt::ReturnStmtClass:
EmitReturnStmt(cast<ReturnStmt>(*S));
break;
138 case Stmt::SwitchStmtClass:
EmitSwitchStmt(cast<SwitchStmt>(*S));
break;
139 case Stmt::GCCAsmStmtClass:
140 case Stmt::MSAsmStmtClass:
EmitAsmStmt(cast<AsmStmt>(*S));
break;
141 case Stmt::CapturedStmtClass: {
146 case Stmt::ObjCAtTryStmtClass:
149 case Stmt::ObjCAtCatchStmtClass:
151 "@catch statements should be handled by EmitObjCAtTryStmt");
152 case Stmt::ObjCAtFinallyStmtClass:
154 "@finally statements should be handled by EmitObjCAtTryStmt");
155 case Stmt::ObjCAtThrowStmtClass:
158 case Stmt::ObjCAtSynchronizedStmtClass:
161 case Stmt::ObjCForCollectionStmtClass:
164 case Stmt::ObjCAutoreleasePoolStmtClass:
168 case Stmt::CXXTryStmtClass:
171 case Stmt::CXXForRangeStmtClass:
174 case Stmt::SEHTryStmtClass:
177 case Stmt::OMPParallelDirectiveClass:
180 case Stmt::OMPSimdDirectiveClass:
183 case Stmt::OMPForDirectiveClass:
186 case Stmt::OMPForSimdDirectiveClass:
189 case Stmt::OMPSectionsDirectiveClass:
192 case Stmt::OMPSectionDirectiveClass:
195 case Stmt::OMPSingleDirectiveClass:
198 case Stmt::OMPMasterDirectiveClass:
201 case Stmt::OMPCriticalDirectiveClass:
204 case Stmt::OMPParallelForDirectiveClass:
207 case Stmt::OMPParallelForSimdDirectiveClass:
210 case Stmt::OMPParallelSectionsDirectiveClass:
213 case Stmt::OMPTaskDirectiveClass:
216 case Stmt::OMPTaskyieldDirectiveClass:
219 case Stmt::OMPBarrierDirectiveClass:
222 case Stmt::OMPTaskwaitDirectiveClass:
225 case Stmt::OMPTaskgroupDirectiveClass:
228 case Stmt::OMPFlushDirectiveClass:
231 case Stmt::OMPOrderedDirectiveClass:
234 case Stmt::OMPAtomicDirectiveClass:
237 case Stmt::OMPTargetDirectiveClass:
240 case Stmt::OMPTeamsDirectiveClass:
243 case Stmt::OMPCancellationPointDirectiveClass:
246 case Stmt::OMPCancelDirectiveClass:
253 switch (S->getStmtClass()) {
254 default:
return false;
255 case Stmt::NullStmtClass:
break;
256 case Stmt::CompoundStmtClass:
EmitCompoundStmt(cast<CompoundStmt>(*S));
break;
257 case Stmt::DeclStmtClass:
EmitDeclStmt(cast<DeclStmt>(*S));
break;
258 case Stmt::LabelStmtClass:
EmitLabelStmt(cast<LabelStmt>(*S));
break;
259 case Stmt::AttributedStmtClass:
261 case Stmt::GotoStmtClass:
EmitGotoStmt(cast<GotoStmt>(*S));
break;
262 case Stmt::BreakStmtClass:
EmitBreakStmt(cast<BreakStmt>(*S));
break;
263 case Stmt::ContinueStmtClass:
EmitContinueStmt(cast<ContinueStmt>(*S));
break;
264 case Stmt::DefaultStmtClass:
EmitDefaultStmt(cast<DefaultStmt>(*S));
break;
265 case Stmt::CaseStmtClass:
EmitCaseStmt(cast<CaseStmt>(*S));
break;
266 case Stmt::SEHLeaveStmtClass:
EmitSEHLeaveStmt(cast<SEHLeaveStmt>(*S));
break;
278 "LLVM IR generation of compound statement ('{}')");
292 E = S.
body_end()-GetLast; I != E; ++I)
302 while (
const LabelStmt *LS = dyn_cast<LabelStmt>(LastStmt)) {
304 LastStmt = LS->getSubStmt();
309 QualType ExprTy = cast<Expr>(LastStmt)->getType();
327 llvm::BranchInst *BI = dyn_cast<llvm::BranchInst>(BB->getTerminator());
336 if (!BI || !BI->isUnconditional())
340 if (BI != BB->begin())
343 BB->replaceAllUsesWith(BI->getSuccessor(0));
344 BI->eraseFromParent();
345 BB->eraseFromParent();
349 llvm::BasicBlock *CurBB =
Builder.GetInsertBlock();
354 if (IsFinished && BB->use_empty()) {
361 if (CurBB && CurBB->getParent())
362 CurFn->getBasicBlockList().insertAfter(CurBB, BB);
364 CurFn->getBasicBlockList().push_back(BB);
372 llvm::BasicBlock *CurBB =
Builder.GetInsertBlock();
374 if (!CurBB || CurBB->getTerminator()) {
386 bool inserted =
false;
387 for (llvm::User *u : block->users()) {
388 if (llvm::Instruction *insn = dyn_cast<llvm::Instruction>(u)) {
389 CurFn->getBasicBlockList().insertAfter(insn->getParent(), block);
396 CurFn->getBasicBlockList().push_back(block);
404 if (Dest.
isValid())
return Dest;
442 assert(!Labels.empty());
448 i = Labels.begin(), e = Labels.end(); i != e; ++i) {
449 assert(
CGF.LabelMap.count(*i));
451 assert(dest.getScopeDepth().isValid());
452 assert(innermostScope.encloses(dest.getScopeDepth()));
453 dest.setScopeDepth(innermostScope);
458 ParentScope->Labels.append(Labels.begin(), Labels.end());
470 switch (SubStmt->getStmtClass()) {
471 case Stmt::DoStmtClass:
474 case Stmt::ForStmtClass:
477 case Stmt::WhileStmtClass:
480 case Stmt::CXXForRangeStmtClass:
508 llvm::BasicBlock *CurBB =
Builder.GetInsertBlock();
515 cast<llvm::PHINode>(IndGotoBB->begin())->addIncoming(V, CurBB);
536 std::swap(Executed, Skipped);
555 llvm::BasicBlock *ElseBlock = ContBlock;
594 llvm::BranchInst *CondBr,
604 for (
const auto *
Attr : Attrs) {
605 const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(
Attr);
611 LoopHintAttr::OptionType Option = LH->getOption();
612 LoopHintAttr::LoopHintState
State = LH->getState();
613 const char *MetadataName;
615 case LoopHintAttr::Vectorize:
616 case LoopHintAttr::VectorizeWidth:
617 MetadataName =
"llvm.loop.vectorize.width";
619 case LoopHintAttr::Interleave:
620 case LoopHintAttr::InterleaveCount:
621 MetadataName =
"llvm.loop.interleave.count";
623 case LoopHintAttr::Unroll:
625 MetadataName = State == LoopHintAttr::Disable ?
"llvm.loop.unroll.disable"
626 :
"llvm.loop.unroll.full";
628 case LoopHintAttr::UnrollCount:
629 MetadataName =
"llvm.loop.unroll.count";
633 Expr *ValueExpr = LH->getValue();
636 llvm::APSInt ValueAPS =
638 ValueInt =
static_cast<int>(ValueAPS.getSExtValue());
641 llvm::Constant *
Value;
642 llvm::MDString *Name;
644 case LoopHintAttr::Vectorize:
645 case LoopHintAttr::Interleave:
646 if (State != LoopHintAttr::Disable) {
649 Name = llvm::MDString::get(Context,
"llvm.loop.vectorize.enable");
656 case LoopHintAttr::VectorizeWidth:
657 case LoopHintAttr::InterleaveCount:
658 case LoopHintAttr::UnrollCount:
659 Name = llvm::MDString::get(Context, MetadataName);
660 Value = llvm::ConstantInt::get(
Int32Ty, ValueInt);
662 case LoopHintAttr::Unroll:
663 Name = llvm::MDString::get(Context, MetadataName);
669 OpValues.push_back(Name);
671 OpValues.push_back(llvm::ConstantAsMetadata::get(Value));
674 Metadata.push_back(llvm::MDNode::get(Context, OpValues));
678 if (!Metadata.empty()) {
680 llvm::MDNode *LoopID = llvm::MDNode::get(Context, Metadata);
681 LoopID->replaceOperandWith(0, LoopID);
683 CondBr->setMetadata(
"llvm.loop", LoopID);
701 BreakContinueStack.push_back(BreakContinue(LoopExit, LoopHeader));
722 bool EmitBoolCondBranch =
true;
723 if (llvm::ConstantInt *
C = dyn_cast<llvm::ConstantInt>(BoolCondVal))
725 EmitBoolCondBranch =
false;
729 if (EmitBoolCondBranch) {
730 llvm::BasicBlock *ExitBlock = LoopExit.
getBlock();
733 llvm::BranchInst *CondBr =
Builder.CreateCondBr(
734 BoolCondVal, LoopBody, ExitBlock,
737 if (ExitBlock != LoopExit.
getBlock()) {
755 BreakContinueStack.pop_back();
771 if (!EmitBoolCondBranch)
783 BreakContinueStack.push_back(BreakContinue(LoopExit, LoopCond));
806 BreakContinueStack.pop_back();
810 bool EmitBoolCondBranch =
true;
811 if (llvm::ConstantInt *
C = dyn_cast<llvm::ConstantInt>(BoolCondVal))
813 EmitBoolCondBranch =
false;
816 if (EmitBoolCondBranch) {
818 llvm::BranchInst *CondBr =
Builder.CreateCondBr(
819 BoolCondVal, LoopBody, LoopExit.
getBlock(),
820 createProfileWeightsForLoop(S.
getCond(), BackedgeCount));
833 if (!EmitBoolCondBranch)
851 llvm::BasicBlock *CondBlock = Continue.
getBlock();
864 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
876 llvm::BasicBlock *ExitBlock = LoopExit.
getBlock();
879 if (ForScope.requiresCleanups())
888 llvm::BranchInst *CondBr =
Builder.CreateCondBr(
889 BoolCondVal, ForBody, ExitBlock,
895 if (ExitBlock != LoopExit.
getBlock()) {
920 BreakContinueStack.pop_back();
922 ConditionScope.ForceCleanup();
927 ForScope.ForceCleanup();
956 llvm::BasicBlock *ExitBlock = LoopExit.
getBlock();
957 if (ForScope.requiresCleanups())
966 llvm::BranchInst *CondBr =
Builder.CreateCondBr(
967 BoolCondVal, ForBody, ExitBlock,
973 if (ExitBlock != LoopExit.
getBlock()) {
985 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
999 BreakContinueStack.pop_back();
1003 ForScope.ForceCleanup();
1011 void CodeGenFunction::EmitReturnOfRValue(
RValue RV,
QualType Ty) {
1031 Builder.ClearInsertionPoint();
1043 dyn_cast_or_null<ExprWithCleanups>(RV)) {
1045 RV = cleanups->getSubExpr();
1096 ++NumSimpleReturnExprs;
1108 for (
const auto *I : S.
decls())
1113 assert(!BreakContinueStack.empty() &&
"break stmt not in a loop or switch!");
1125 assert(!BreakContinueStack.empty() &&
"continue stmt not in a loop!");
1140 assert(S.
getRHS() &&
"Expected RHS value in CaseStmt");
1153 if (LHS.isSigned() ? RHS.slt(LHS) : RHS.ult(LHS))
1156 llvm::APInt Range = RHS - LHS;
1158 if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) {
1161 unsigned NCases = Range.getZExtValue() + 1;
1166 uint64_t Weight = Total / NCases, Rem = Total % NCases;
1167 for (
unsigned I = 0; I != NCases; ++I) {
1169 SwitchWeights->push_back(Weight + (Rem ? 1 : 0));
1172 SwitchInsn->addCase(
Builder.getInt(LHS), CaseDest);
1180 llvm::BasicBlock *RestoreBB =
Builder.GetInsertBlock();
1185 llvm::BasicBlock *FalseDest = CaseRangeBlock;
1188 CurFn->getBasicBlockList().push_back(CaseRangeBlock);
1189 Builder.SetInsertPoint(CaseRangeBlock);
1193 Builder.CreateSub(SwitchInsn->getCondition(),
Builder.getInt(LHS));
1197 llvm::MDNode *Weights =
nullptr;
1198 if (SwitchWeights) {
1200 uint64_t DefaultCount = (*SwitchWeights)[0];
1201 Weights = createProfileWeights(ThisCount, DefaultCount);
1206 (*SwitchWeights)[0] += ThisCount;
1208 Builder.CreateCondBr(Cond, CaseDest, FalseDest, Weights);
1212 Builder.SetInsertPoint(RestoreBB);
1214 Builder.ClearInsertionPoint();
1234 llvm::ConstantInt *CaseVal =
1243 JumpDest Block = BreakContinueStack.back().BreakBlock;
1249 SwitchInsn->addCase(CaseVal, Block.
getBlock());
1253 if (
Builder.GetInsertBlock()) {
1255 Builder.ClearInsertionPoint();
1265 SwitchInsn->addCase(CaseVal, CaseDest);
1280 while (NextCase && NextCase->
getRHS() ==
nullptr) {
1282 llvm::ConstantInt *CaseVal =
1292 SwitchInsn->addCase(CaseVal, CaseDest);
1301 llvm::BasicBlock *DefaultBlock = SwitchInsn->getDefaultDest();
1302 assert(DefaultBlock->empty() &&
1303 "EmitDefaultStmt: Default block already defined?");
1344 if (
const SwitchCase *SC = dyn_cast<SwitchCase>(S)) {
1358 if (!Case && isa<BreakStmt>(S))
1363 if (
const CompoundStmt *CS = dyn_cast<CompoundStmt>(S)) {
1371 bool HadSkippedDecl =
false;
1375 for (; Case && I != E; ++I) {
1376 HadSkippedDecl |= isa<DeclStmt>(*I);
1391 for (++I; I != E; ++I)
1401 assert(FoundCase &&
"Didn't find case but returned fallthrough?");
1416 for (; I != E; ++I) {
1427 for (++I; I != E; ++I)
1452 ResultStmts.push_back(S);
1461 const llvm::APSInt &ConstantCondValue,
1473 if (
const DefaultStmt *DS = dyn_cast<DefaultStmt>(Case)) {
1479 const CaseStmt *CS = cast<CaseStmt>(Case);
1481 if (CS->
getRHS())
return false;
1506 bool FoundCase =
false;
1515 llvm::SwitchInst *SavedSwitchInsn = SwitchInsn;
1517 llvm::BasicBlock *SavedCRBlock = CaseRangeBlock;
1521 llvm::APSInt ConstantCondValue;
1539 SwitchInsn =
nullptr;
1543 for (
unsigned i = 0, e = CaseStmts.size(); i != e; ++i)
1549 SwitchInsn = SavedSwitchInsn;
1567 SwitchInsn =
Builder.CreateSwitch(CondV, DefaultBlock);
1570 uint64_t DefaultCount = 0;
1571 unsigned NumCases = 0;
1575 if (isa<DefaultStmt>(Case))
1580 SwitchWeights->reserve(NumCases);
1583 SwitchWeights->push_back(DefaultCount);
1585 CaseRangeBlock = DefaultBlock;
1588 Builder.ClearInsertionPoint();
1593 if (!BreakContinueStack.empty())
1594 OuterContinue = BreakContinueStack.back().ContinueBlock;
1596 BreakContinueStack.push_back(BreakContinue(SwitchExit, OuterContinue));
1601 BreakContinueStack.pop_back();
1605 SwitchInsn->setDefaultDest(CaseRangeBlock);
1608 if (!DefaultBlock->getParent()) {
1616 DefaultBlock->replaceAllUsesWith(SwitchExit.
getBlock());
1617 delete DefaultBlock;
1627 if (SwitchWeights) {
1628 assert(SwitchWeights->size() == 1 + SwitchInsn->getNumCases() &&
1629 "switch weights do not match switch cases");
1631 if (SwitchWeights->size() > 1)
1632 SwitchInsn->setMetadata(llvm::LLVMContext::MD_prof,
1633 createProfileWeights(*SwitchWeights));
1634 delete SwitchWeights;
1636 SwitchInsn = SavedSwitchInsn;
1637 SwitchWeights = SavedSwitchWeights;
1638 CaseRangeBlock = SavedCRBlock;
1646 while (*Constraint) {
1647 switch (*Constraint) {
1659 while (Constraint[1] && Constraint[1] !=
',')
1664 Result += *Constraint;
1665 while (Constraint[1] && Constraint[1] == *Constraint)
1676 "Must pass output names to constraints with a symbolic name");
1680 OutCons->size(), Index);
1681 assert(result &&
"Could not resolve symbolic name"); (void)result;
1682 Result += llvm::utostr(Index);
1709 AsmLabelAttr *
Attr = Variable->
getAttr<AsmLabelAttr>();
1712 StringRef Register = Attr->getLabel();
1718 !Info.allowsRegister()) {
1724 return (EarlyClobber ?
"&{" :
"{") + Register.str() +
"}";
1730 std::string &ConstraintStr,
1739 if (Size <= 64 && llvm::isPowerOf2_64(Size)) {
1741 Ty = llvm::PointerType::getUnqual(Ty);
1747 ConstraintStr +=
'*';
1752 ConstraintStr +=
'*';
1760 const Expr *InputExpr,
1761 std::string &ConstraintStr) {
1769 "Required-immediate inlineasm arg isn't constant?");
1778 return EmitAsmInputLValue(Info, Dest, InputExpr->
getType(), ConstraintStr,
1790 Locs.push_back(llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
1793 if (!StrVal.empty()) {
1799 for (
unsigned i = 0, e = StrVal.size()-1; i != e; ++i) {
1800 if (StrVal[i] !=
'\n')
continue;
1803 Locs.push_back(llvm::ConstantAsMetadata::get(
1821 if (
const GCCAsmStmt *GAS = dyn_cast<GCCAsmStmt>(&S))
1822 Name = GAS->getOutputName(i);
1825 assert(IsValid &&
"Failed to parse output constraint");
1826 OutputConstraintInfos.push_back(Info);
1829 for (
unsigned i = 0, e = S.
getNumInputs(); i != e; i++) {
1831 if (
const GCCAsmStmt *GAS = dyn_cast<GCCAsmStmt>(&S))
1832 Name = GAS->getInputName(i);
1837 assert(IsValid &&
"Failed to parse input constraint"); (void)IsValid;
1838 InputConstraintInfos.push_back(Info);
1841 std::string Constraints;
1843 std::vector<LValue> ResultRegDests;
1844 std::vector<QualType> ResultRegQualTys;
1845 std::vector<llvm::Type *> ResultRegTypes;
1846 std::vector<llvm::Type *> ResultTruncRegTypes;
1847 std::vector<llvm::Type *> ArgTypes;
1848 std::vector<llvm::Value*> Args;
1851 std::string InOutConstraints;
1852 std::vector<llvm::Value*> InOutArgs;
1853 std::vector<llvm::Type*> InOutArgTypes;
1861 bool ReadOnly =
true, ReadNone =
true;
1879 if (!Constraints.empty())
1885 Constraints +=
"=" + OutputConstraint;
1886 ResultRegQualTys.push_back(OutExpr->getType());
1887 ResultRegDests.push_back(Dest);
1889 ResultTruncRegTypes.push_back(ResultRegTypes.back());
1896 for (InputNo = 0; InputNo != S.
getNumInputs(); ++InputNo) {
1901 assert(InputNo != S.
getNumInputs() &&
"Didn't find matching input!");
1904 QualType OutputType = OutExpr->getType();
1907 if (
getContext().getTypeSize(OutputType) < InputSize) {
1912 if (llvm::Type* AdjTy =
1913 getTargetHooks().adjustInlineAsmType(*
this, OutputConstraint,
1914 ResultRegTypes.back()))
1915 ResultRegTypes.back() = AdjTy;
1918 diag::err_asm_invalid_type_in_input)
1919 << OutExpr->getType() << OutputConstraint;
1922 ArgTypes.push_back(Dest.getAddress()->getType());
1923 Args.push_back(Dest.getAddress());
1924 Constraints +=
"=*";
1925 Constraints += OutputConstraint;
1926 ReadOnly = ReadNone =
false;
1930 InOutConstraints +=
',';
1937 if (llvm::Type* AdjTy =
1940 Arg =
Builder.CreateBitCast(Arg, AdjTy);
1943 InOutConstraints += llvm::utostr(i);
1945 InOutConstraints += OutputConstraint;
1947 InOutArgTypes.push_back(Arg->getType());
1948 InOutArgs.push_back(Arg);
1954 if (isa<MSAsmStmt>(&S)) {
1960 *
this, ReturnSlot, Constraints, ResultRegTypes, ResultTruncRegTypes,
1966 for (
unsigned i = 0, e = S.
getNumInputs(); i != e; i++) {
1974 if (!Constraints.empty())
1980 &OutputConstraintInfos);
1986 llvm::Value *Arg = EmitAsmInput(Info, InputExpr, Constraints);
1995 QualType OutputType = S.getOutputExpr(Output)->getType();
2001 if (isa<llvm::PointerType>(Arg->getType()))
2004 if (isa<llvm::IntegerType>(OutputTy))
2005 Arg =
Builder.CreateZExt(Arg, OutputTy);
2006 else if (isa<llvm::PointerType>(OutputTy))
2009 assert(OutputTy->isFloatingPointTy() &&
"Unexpected output type");
2010 Arg =
Builder.CreateFPExt(Arg, OutputTy);
2014 if (llvm::Type* AdjTy =
2015 getTargetHooks().adjustInlineAsmType(*
this, InputConstraint,
2017 Arg =
Builder.CreateBitCast(Arg, AdjTy);
2020 << InputExpr->
getType() << InputConstraint;
2022 ArgTypes.push_back(Arg->getType());
2023 Args.push_back(Arg);
2024 Constraints += InputConstraint;
2028 for (
unsigned i = 0, e = InOutArgs.size(); i != e; i++) {
2029 ArgTypes.push_back(InOutArgTypes[i]);
2030 Args.push_back(InOutArgs[i]);
2032 Constraints += InOutConstraints;
2038 if (Clobber ==
"memory")
2039 ReadOnly = ReadNone =
false;
2040 else if (Clobber !=
"cc")
2043 if (!Constraints.empty())
2046 Constraints +=
"~{";
2047 Constraints += Clobber;
2053 if (!MachineClobbers.empty()) {
2054 if (!Constraints.empty())
2056 Constraints += MachineClobbers;
2059 llvm::Type *ResultType;
2060 if (ResultRegTypes.empty())
2062 else if (ResultRegTypes.size() == 1)
2063 ResultType = ResultRegTypes[0];
2065 ResultType = llvm::StructType::get(
getLLVMContext(), ResultRegTypes);
2067 llvm::FunctionType *FTy =
2068 llvm::FunctionType::get(ResultType, ArgTypes,
false);
2071 llvm::InlineAsm::AsmDialect AsmDialect = isa<MSAsmStmt>(&
S) ?
2072 llvm::InlineAsm::AD_Intel : llvm::InlineAsm::AD_ATT;
2073 llvm::InlineAsm *IA =
2074 llvm::InlineAsm::get(FTy, AsmString, Constraints, HasSideEffect,
2076 llvm::CallInst *Result =
Builder.CreateCall(IA, Args);
2077 Result->addAttribute(llvm::AttributeSet::FunctionIndex,
2078 llvm::Attribute::NoUnwind);
2081 if (!HasSideEffect) {
2083 Result->addAttribute(llvm::AttributeSet::FunctionIndex,
2084 llvm::Attribute::ReadNone);
2086 Result->addAttribute(llvm::AttributeSet::FunctionIndex,
2087 llvm::Attribute::ReadOnly);
2092 if (
const GCCAsmStmt *gccAsmStmt = dyn_cast<GCCAsmStmt>(&S)) {
2098 Result->setMetadata(
"srcloc",
2100 llvm::ConstantAsMetadata::get(Loc)));
2104 std::vector<llvm::Value*> RegResults;
2105 if (ResultRegTypes.size() == 1) {
2106 RegResults.push_back(Result);
2108 for (
unsigned i = 0, e = ResultRegTypes.size(); i != e; ++i) {
2110 RegResults.push_back(Tmp);
2114 assert(RegResults.size() == ResultRegTypes.size());
2115 assert(RegResults.size() == ResultTruncRegTypes.size());
2116 assert(RegResults.size() == ResultRegDests.size());
2117 for (
unsigned i = 0, e = RegResults.size(); i != e; ++i) {
2122 if (ResultRegTypes[i] != ResultTruncRegTypes[i]) {
2123 llvm::Type *TruncTy = ResultTruncRegTypes[i];
2127 if (TruncTy->isFloatingPointTy())
2128 Tmp =
Builder.CreateFPTrunc(Tmp, TruncTy);
2129 else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) {
2131 Tmp =
Builder.CreateTrunc(Tmp,
2133 Tmp =
Builder.CreateIntToPtr(Tmp, TruncTy);
2134 }
else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) {
2136 Tmp =
Builder.CreatePtrToInt(Tmp,
2138 Tmp =
Builder.CreateTrunc(Tmp, TruncTy);
2139 }
else if (TruncTy->isIntegerTy()) {
2140 Tmp =
Builder.CreateTrunc(Tmp, TruncTy);
2141 }
else if (TruncTy->isVectorTy()) {
2142 Tmp =
Builder.CreateBitCast(Tmp, TruncTy);
2161 I != E; ++I, ++CurField) {
2163 if (CurField->hasCapturedVLAType()) {
2164 auto VAT = CurField->getCapturedVLAType();
2202 "CapturedStmtInfo should be set when generating the captured function");
2206 assert(CD->
hasBody() &&
"missing CapturedDecl body");
2225 F->addFnAttr(llvm::Attribute::NoUnwind);
2230 CD->
getBody()->getLocStart());
2233 assert(DeclPtr &&
"missing context parameter for CapturedStmt");
2238 Ctx.getTagDeclType(RD));
2239 for (
auto *FD : RD->
fields()) {
2240 if (FD->hasCapturedVLAType()) {
2243 auto VAT = FD->getCapturedVLAType();
2244 VLASizeMap[VAT->getSizeExpr()] = ExprArg;
void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init, ArrayRef< VarDecl * > ArrayIndexes)
void EmitIndirectGotoStmt(const IndirectGotoStmt &S)
const SwitchCase * getNextSwitchCase() const
virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S)
Emit the captured statement body.
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
unsigned getNumOutputs() const
void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S)
StringRef getName() const
void EmitSEHLeaveStmt(const SEHLeaveStmt &S)
CodeGenTypes & getTypes()
bool isEvaluatable(const ASTContext &Ctx) const
llvm::Type * ConvertTypeForMem(QualType T)
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount)
void EmitGotoStmt(const GotoStmt &S)
bool resolveSymbolicName(const char *&Name, ConstraintInfo *OutputConstraints, unsigned NumOutputs, unsigned &Index) const
void EmitAttributedStmt(const AttributedStmt &S)
bool hasMatchingInput() const
Return true if this output operand has a matching (tied) input operand.
llvm::Module & getModule() const
void EmitCXXTryStmt(const CXXTryStmt &S)
const TargetInfo & getTarget() const
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
static stable_iterator stable_end()
Create a stable reference to the bottom of the EH stack.
const Expr * getOutputExpr(unsigned i) const
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
Represents an attribute applied to a statement.
llvm::Value * EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
void EmitAutoVarDecl(const VarDecl &D)
const llvm::DataLayout & getDataLayout() const
void EmitOMPOrderedDirective(const OMPOrderedDirective &S)
bool validateOutputConstraint(ConstraintInfo &Info) const
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)
QualType getRecordType(const RecordDecl *Decl) const
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
const Stmt * getElse() const
SourceLocation getLocStart() const LLVM_READONLY
const LangOptions & getLangOpts() const
LValue EmitLValueForFieldInitialization(LValue Base, const FieldDecl *Field)
unsigned getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it...
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
const CGFunctionInfo & arrangeFreeFunctionDeclaration(QualType ResTy, const FunctionArgList &Args, const FunctionType::ExtInfo &Info, bool isVariadic)
llvm::Value * getAddress() const
void EmitOMPParallelForSimdDirective(const OMPParallelForSimdDirective &S)
void EmitOMPCriticalDirective(const OMPCriticalDirective &S)
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
field_iterator field_begin() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
void EmitLabel(const LabelDecl *D)
llvm::Value * ReturnValue
void SimplifyForwardingBlocks(llvm::BasicBlock *BB)
JumpDest getJumpDestForLabel(const LabelDecl *S)
void EmitCXXForRangeStmt(const CXXForRangeStmt &S, ArrayRef< const Attr * > Attrs=None)
void EmitOMPSimdDirective(const OMPSimdDirective &S)
void setScopeDepth(EHScopeStack::stable_iterator depth)
unsigned getNumInputs() const
CGDebugInfo * getDebugInfo()
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
void addLabel(const LabelDecl *label)
RValue EmitReferenceBindingToExpr(const Expr *E)
Emits a reference binding to the passed in expression.
bool isReferenceType() const
virtual void setContextValue(llvm::Value *V)
llvm::CallSite EmitCallOrInvoke(llvm::Value *Callee, ArrayRef< llvm::Value * > Args, const Twine &Name="")
SourceLocation getLBracLoc() const
static bool FindCaseStatementsForValue(const SwitchStmt &S, const llvm::APSInt &ConstantCondValue, SmallVectorImpl< const Stmt * > &ResultStmts, ASTContext &C, const SwitchCase *&ResultCase)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
StorageClass getStorageClass() const
Returns the storage class as written in the source. For the computed linkage of symbol, see getLinkage.
const VarDecl * getNRVOCandidate() const
Retrieve the variable that might be used for the named return value optimization. ...
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment=CharUnits())
static bool hasScalarEvaluationKind(QualType T)
StringRef getOutputConstraint(unsigned i) const
void EmitDoStmt(const DoStmt &S, ArrayRef< const Attr * > Attrs=None)
void pop()
End the current loop.
bool isValidGCCRegisterName(StringRef Name) const
Returns whether the passed in string is a valid register name according to GCC.
void EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S)
RAII for correct setting/restoring of CapturedStmtInfo.
field_range fields() const
void EmitContinueStmt(const ContinueStmt &S)
void EmitOMPTargetDirective(const OMPTargetDirective &S)
llvm::Value * getAggregateAddr() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep)
Creates clause with a list of variables VL and a linear step Step.
void EmitSwitchStmt(const SwitchStmt &S)
LabelStmt * getStmt() const
bool isObviouslyBranchWithoutCleanups(JumpDest Dest) const
void incrementProfileCounter(const Stmt *S)
Increment the profiler's counter for the given statement.
void EmitStmt(const Stmt *S)
void EmitOMPParallelDirective(const OMPParallelDirective &S)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
llvm::Function * EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K)
bool requiresCleanups() const
Determine whether this scope requires any cleanups.
virtual FieldDecl * getThisFieldDecl() const
void EmitDefaultStmt(const DefaultStmt &S)
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
const RecordDecl * getCapturedRecordDecl() const
Retrieve the record declaration for captured variables.
void EmitCaseStmtRange(const CaseStmt &S)
uint64_t getCurrentProfileCount()
This represents the body of a CapturedStmt, and serves as its DeclContext.
LValue EmitLValueForField(LValue Base, const FieldDecl *Field)
SourceLocation getAsmLoc() const
void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S)
const TargetCodeGenInfo & getTargetCodeGenInfo()
Expr * IgnoreParenNoopCasts(ASTContext &Ctx) LLVM_READONLY
virtual std::string convertConstraint(const char *&Constraint) const
SourceLocation getBodyRBrace() const
std::string generateAsmString(const ASTContext &C) const
Assemble final IR asm string.
Exposes information about the current target.
virtual StringRef getHelperName() const
Get the name of the capture helper.
static TypeEvaluationKind getEvaluationKind(QualType T)
LabelDecl * getDecl() const
bool empty() const
Determines whether the exception-scopes stack is empty.
const Expr * getInputExpr(unsigned i) const
llvm::Value * GenerateCapturedStmtArgument(const CapturedStmt &S)
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
void EmitCaseStmt(const CaseStmt &S)
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "while" statement, if any.
void EmitOMPTeamsDirective(const OMPTeamsDirective &S)
void SetInternalFunctionAttributes(const Decl *D, llvm::Function *F, const CGFunctionInfo &FI)
Stmt * getBody() const override
LabelDecl * getConstantTarget()
bool haveRegionCounts() const
void EmitSEHTryStmt(const SEHTryStmt &S)
ASTContext & getContext() const
llvm::BasicBlock * getBlock() const
EHScopeStack::stable_iterator getScopeDepth() const
llvm::Value * EmitCompoundStmtWithoutScope(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
static llvm::MDNode * getAsmSrcLocInfo(const StringLiteral *Str, CodeGenFunction &CGF)
stable_iterator stable_begin() const
llvm::LLVMContext & getLLVMContext()
llvm::BasicBlock * GetIndirectGotoBlock()
llvm::IntegerType * Int32Ty
const SwitchCase * getSwitchCaseList() const
void EmitOMPMasterDirective(const OMPMasterDirective &S)
bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
llvm::Function * GenerateCapturedStmtFunction(const CapturedStmt &S)
Creates the outlined function for a CapturedStmt.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
void ResolveBranchFixups(llvm::BasicBlock *Target)
void EmitOMPBarrierDirective(const OMPBarrierDirective &S)
static CSFC_Result CollectStatementsForCase(const Stmt *S, const SwitchCase *Case, bool &FoundCase, SmallVectorImpl< const Stmt * > &ResultStmts)
virtual llvm::Value * getContextValue() const
unsigned getTiedOperand() const
StringRef getInputConstraint(unsigned i) const
The result type of a method or function.
SourceLocation getLocationOfByte(unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, const TargetInfo &Target) const
bool isCXXThisExprCaptured() const
void EmitDeclStmt(const DeclStmt &S)
void EmitAnyExprToMem(const Expr *E, llvm::Value *Location, Qualifiers Quals, bool IsInitializer)
LabelDecl * getLabel() const
void EmitOMPFlushDirective(const OMPFlushDirective &S)
bool HaveInsertPoint() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
This captures a statement into a function. For example, the following pragma annotated compound state...
ASTContext & getContext() const
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
void EmitOMPForDirective(const OMPForDirective &S)
void EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr, QualType EltTy, bool isVolatile=false, CharUnits Alignment=CharUnits::Zero(), bool isAssignment=false)
llvm::Value * EvaluateExprAsBool(const Expr *E)
void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)
capture_init_iterator capture_init_end() const
Retrieve the iterator pointing one past the last initialization argument.
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result)
const Expr * getCond() const
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
bool allowsMemory() const
param_iterator param_begin() const
Retrieve an iterator pointing to the first parameter decl.
void EmitOMPTaskgroupDirective(const OMPTaskgroupDirective &S)
const CodeGenOptions & getCodeGenOpts() const
void EmitOMPSingleDirective(const OMPSingleDirective &S)
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
const LangOptions & getLangOpts() const
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "switch" statement, if any.
llvm::AllocaInst * CreateMemTemp(QualType T, const Twine &Name="tmp")
void EmitOMPForSimdDirective(const OMPForSimdDirective &S)
void EmitOMPAtomicDirective(const OMPAtomicDirective &S)
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
void EmitOMPSectionDirective(const OMPSectionDirective &S)
virtual llvm::Type * adjustInlineAsmType(CodeGen::CodeGenFunction &CGF, StringRef Constraint, llvm::Type *Ty) const
void EmitOMPSectionsDirective(const OMPSectionsDirective &S)
void EmitForStmt(const ForStmt &S, ArrayRef< const Attr * > Attrs=None)
const CGFunctionInfo * CurFnInfo
void enterFullExpression(const ExprWithCleanups *E)
void EmitDecl(const Decl &D)
void FinishFunction(SourceLocation EndLoc=SourceLocation())
SourceLocation getExprLoc() const LLVM_READONLY
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S)
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "if" statement, if any.
void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S)
LValue InitCapturedStruct(const CapturedStmt &S)
const Stmt * getBody() const
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
void EmitOMPParallelForDirective(const OMPParallelForDirective &S)
bool hasTiedOperand() const
Return true if this input operand is a matching constraint that ties it to an output operand...
llvm::IntegerType * IntPtrTy
StringRef getString() const
void EmitOMPCancelDirective(const OMPCancelDirective &S)
const Expr * getRetValue() const
void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S)
body_iterator body_begin()
Stmt *const * const_body_iterator
void EmitAggExpr(const Expr *E, AggValueSlot AS)
const Stmt * getThen() const
JumpDest ReturnBlock
ReturnBlock - Unified return block.
static bool hasAggregateEvaluationKind(QualType T)
static stable_iterator invalid()
API for captured statement code generation.
static std::string SimplifyConstraint(const char *Constraint, const TargetInfo &Target, SmallVectorImpl< TargetInfo::ConstraintInfo > *OutCons=nullptr)
void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S)
DeclStmt * getBeginEndStmt()
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
void EmitAsmStmt(const AsmStmt &S)
static std::string AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr, const TargetInfo &Target, CodeGenModule &CGM, const AsmStmt &Stmt, const bool EarlyClobber)
llvm::PointerType * Int8PtrTy
const TargetInfo & Target
bool allowsRegister() const
bool isNRVOVariable() const
Determine whether this local variable can be used with the named return value optimization (NRVO)...
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
SourceLocation getLocStart() const LLVM_READONLY
StringRef getClobber(unsigned i) const
ImplicitParamDecl * getContextParam() const
Retrieve the parameter containing captured variables.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
ABIArgInfo & getReturnInfo()
SourceManager & getSourceManager()
DeclStmt * getRangeStmt()
void EmitStopPoint(const Stmt *S)
EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.
ArrayRef< const Attr * > getAttrs() const
unsigned NextCleanupDestIndex
param_iterator param_end() const
Retrieve an iterator one past the last parameter decl.
void setCurrentStmt(const Stmt *S)
llvm::DenseMap< const VarDecl *, llvm::Value * > NRVOFlags
A mapping from NRVO variables to the flags used to indicate when the NRVO has been applied to this va...
DiagnosticsEngine & getDiags() const
void EmitIfStmt(const IfStmt &S)
void EmitBranch(llvm::BasicBlock *Block)
void EmitReturnStmt(const ReturnStmt &S)
llvm::Type * ConvertType(QualType T)
LValue EmitLValue(const Expr *E)
const Expr * getCond() const
CapturedRegionKind getCapturedRegionKind() const
Retrieve the captured region kind.
void EmitLabelStmt(const LabelStmt &S)
StringRef getNormalizedGCCRegisterName(StringRef Name) const
Returns the "normalized" GCC register name.
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
bool hasNormalCleanups() const
Determines whether there are any normal cleanups on the stack.
Defines the clang::TargetInfo interface.
void ForceCleanup()
Force the emission of cleanups now, instead of waiting until this object is destroyed.
capture_init_iterator capture_init_begin() const
Retrieve the first initialization argument.
CGCapturedStmtInfo * CapturedStmtInfo
bool validateInputConstraint(ConstraintInfo *OutputConstraints, unsigned NumOutputs, ConstraintInfo &info) const
stable_iterator getInnermostNormalCleanup() const
A reference to a declared variable, function, enum, etc. [C99 6.5.1p2].
static RValue get(llvm::Value *V)
bool EmitSimpleStmt(const Stmt *S)
CapturedRegionKind
The different kinds of captured statement.
void EmitBranchThroughCleanup(JumpDest Dest)
static AggValueSlot forAddr(llvm::Value *addr, CharUnits align, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, IsZeroed_t isZeroed=IsNotZeroed)
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
DeclStmt * getLoopVarStmt()
unsigned getNumClobbers() const
SourceLocation getLocation() const
void EmitObjCAtTryStmt(const ObjCAtTryStmt &S)
void EmitWhileStmt(const WhileStmt &S, ArrayRef< const Attr * > Attrs=None)
virtual void addReturnRegisterOutputs(CodeGen::CodeGenFunction &CGF, CodeGen::LValue ReturnValue, std::string &Constraints, std::vector< llvm::Type * > &ResultRegTypes, std::vector< llvm::Type * > &ResultTruncRegTypes, std::vector< CodeGen::LValue > &ResultRegDests, std::string &AsmString, unsigned NumOutputs) const
Adds constraints and types for result registers.
void EmitBlockAfterUses(llvm::BasicBlock *BB)
void assignRegionCounters(const Decl *D, llvm::Function *Fn)
void EmitBreakStmt(const BreakStmt &S)
void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S)
void push(llvm::BasicBlock *Header, llvm::ArrayRef< const Attr * > Attrs=llvm::None)
Begin a new structured loop. The set of staged attributes will be applied to the loop and then cleare...
static bool containsBreak(const Stmt *S)
virtual bool hasBody() const
Returns true if this Decl represents a declaration for a body of code, such as a function or method d...
This class handles loading and caching of source files into memory.
void EmitOMPTaskDirective(const OMPTaskDirective &S)
bool requiresImmediateConstant() const
void EmitCondBrHints(llvm::LLVMContext &Context, llvm::BranchInst *CondBr, ArrayRef< const Attr * > Attrs)
Attr - This represents one attribute.
virtual const char * getClobbers() const =0
Returns a string of target-specific clobbers, in LLVM format.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.