1f22ef01cSRoman Divacky //===--- CodeGenFunction.cpp - Emit LLVM Code from ASTs for a Function ----===// 2f22ef01cSRoman Divacky // 3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure 4f22ef01cSRoman Divacky // 5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source 6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details. 7f22ef01cSRoman Divacky // 8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 9f22ef01cSRoman Divacky // 10f22ef01cSRoman Divacky // This coordinates the per-function state used while generating code. 11f22ef01cSRoman Divacky // 12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 13f22ef01cSRoman Divacky 14f22ef01cSRoman Divacky #include "CodeGenFunction.h" 15f22ef01cSRoman Divacky #include "CodeGenModule.h" 16f22ef01cSRoman Divacky #include "CGDebugInfo.h" 17f22ef01cSRoman Divacky #include "clang/Basic/TargetInfo.h" 18f22ef01cSRoman Divacky #include "clang/AST/APValue.h" 19f22ef01cSRoman Divacky #include "clang/AST/ASTContext.h" 20f22ef01cSRoman Divacky #include "clang/AST/Decl.h" 21f22ef01cSRoman Divacky #include "clang/AST/DeclCXX.h" 22f22ef01cSRoman Divacky #include "clang/AST/StmtCXX.h" 23f22ef01cSRoman Divacky #include "llvm/Target/TargetData.h" 24f22ef01cSRoman Divacky using namespace clang; 25f22ef01cSRoman Divacky using namespace CodeGen; 26f22ef01cSRoman Divacky 27f22ef01cSRoman Divacky CodeGenFunction::CodeGenFunction(CodeGenModule &cgm) 28f22ef01cSRoman Divacky : BlockFunction(cgm, *this, Builder), CGM(cgm), 29f22ef01cSRoman Divacky Target(CGM.getContext().Target), 30f22ef01cSRoman Divacky Builder(cgm.getModule().getContext()), 31f22ef01cSRoman Divacky DebugInfo(0), IndirectBranch(0), 32f22ef01cSRoman Divacky SwitchInsn(0), CaseRangeBlock(0), InvokeDest(0), 33f22ef01cSRoman Divacky CXXThisDecl(0), CXXThisValue(0), CXXVTTDecl(0), CXXVTTValue(0), 34f22ef01cSRoman Divacky ConditionalBranchLevel(0), TerminateHandler(0), TrapBB(0), 35f22ef01cSRoman Divacky UniqueAggrDestructorCount(0) { 36f22ef01cSRoman Divacky LLVMIntTy = ConvertType(getContext().IntTy); 37f22ef01cSRoman Divacky LLVMPointerWidth = Target.getPointerWidth(0); 38f22ef01cSRoman Divacky Exceptions = getContext().getLangOptions().Exceptions; 39f22ef01cSRoman Divacky CatchUndefined = getContext().getLangOptions().CatchUndefined; 40f22ef01cSRoman Divacky CGM.getMangleContext().startNewFunction(); 41f22ef01cSRoman Divacky } 42f22ef01cSRoman Divacky 43f22ef01cSRoman Divacky ASTContext &CodeGenFunction::getContext() const { 44f22ef01cSRoman Divacky return CGM.getContext(); 45f22ef01cSRoman Divacky } 46f22ef01cSRoman Divacky 47f22ef01cSRoman Divacky 48f22ef01cSRoman Divacky llvm::BasicBlock *CodeGenFunction::getBasicBlockForLabel(const LabelStmt *S) { 49f22ef01cSRoman Divacky llvm::BasicBlock *&BB = LabelMap[S]; 50f22ef01cSRoman Divacky if (BB) return BB; 51f22ef01cSRoman Divacky 52f22ef01cSRoman Divacky // Create, but don't insert, the new block. 53f22ef01cSRoman Divacky return BB = createBasicBlock(S->getName()); 54f22ef01cSRoman Divacky } 55f22ef01cSRoman Divacky 56f22ef01cSRoman Divacky llvm::Value *CodeGenFunction::GetAddrOfLocalVar(const VarDecl *VD) { 57f22ef01cSRoman Divacky llvm::Value *Res = LocalDeclMap[VD]; 58f22ef01cSRoman Divacky assert(Res && "Invalid argument to GetAddrOfLocalVar(), no decl!"); 59f22ef01cSRoman Divacky return Res; 60f22ef01cSRoman Divacky } 61f22ef01cSRoman Divacky 62f22ef01cSRoman Divacky llvm::Constant * 63f22ef01cSRoman Divacky CodeGenFunction::GetAddrOfStaticLocalVar(const VarDecl *BVD) { 64f22ef01cSRoman Divacky return cast<llvm::Constant>(GetAddrOfLocalVar(BVD)); 65f22ef01cSRoman Divacky } 66f22ef01cSRoman Divacky 67f22ef01cSRoman Divacky const llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) { 68f22ef01cSRoman Divacky return CGM.getTypes().ConvertTypeForMem(T); 69f22ef01cSRoman Divacky } 70f22ef01cSRoman Divacky 71f22ef01cSRoman Divacky const llvm::Type *CodeGenFunction::ConvertType(QualType T) { 72f22ef01cSRoman Divacky return CGM.getTypes().ConvertType(T); 73f22ef01cSRoman Divacky } 74f22ef01cSRoman Divacky 75f22ef01cSRoman Divacky bool CodeGenFunction::hasAggregateLLVMType(QualType T) { 76f22ef01cSRoman Divacky return T->isRecordType() || T->isArrayType() || T->isAnyComplexType() || 77f22ef01cSRoman Divacky T->isMemberFunctionPointerType(); 78f22ef01cSRoman Divacky } 79f22ef01cSRoman Divacky 80f22ef01cSRoman Divacky void CodeGenFunction::EmitReturnBlock() { 81f22ef01cSRoman Divacky // For cleanliness, we try to avoid emitting the return block for 82f22ef01cSRoman Divacky // simple cases. 83f22ef01cSRoman Divacky llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); 84f22ef01cSRoman Divacky 85f22ef01cSRoman Divacky if (CurBB) { 86f22ef01cSRoman Divacky assert(!CurBB->getTerminator() && "Unexpected terminated block."); 87f22ef01cSRoman Divacky 88f22ef01cSRoman Divacky // We have a valid insert point, reuse it if it is empty or there are no 89f22ef01cSRoman Divacky // explicit jumps to the return block. 90f22ef01cSRoman Divacky if (CurBB->empty() || ReturnBlock->use_empty()) { 91f22ef01cSRoman Divacky ReturnBlock->replaceAllUsesWith(CurBB); 92f22ef01cSRoman Divacky delete ReturnBlock; 93f22ef01cSRoman Divacky } else 94f22ef01cSRoman Divacky EmitBlock(ReturnBlock); 95f22ef01cSRoman Divacky return; 96f22ef01cSRoman Divacky } 97f22ef01cSRoman Divacky 98f22ef01cSRoman Divacky // Otherwise, if the return block is the target of a single direct 99f22ef01cSRoman Divacky // branch then we can just put the code in that block instead. This 100f22ef01cSRoman Divacky // cleans up functions which started with a unified return block. 101f22ef01cSRoman Divacky if (ReturnBlock->hasOneUse()) { 102f22ef01cSRoman Divacky llvm::BranchInst *BI = 103f22ef01cSRoman Divacky dyn_cast<llvm::BranchInst>(*ReturnBlock->use_begin()); 104f22ef01cSRoman Divacky if (BI && BI->isUnconditional() && BI->getSuccessor(0) == ReturnBlock) { 105f22ef01cSRoman Divacky // Reset insertion point and delete the branch. 106f22ef01cSRoman Divacky Builder.SetInsertPoint(BI->getParent()); 107f22ef01cSRoman Divacky BI->eraseFromParent(); 108f22ef01cSRoman Divacky delete ReturnBlock; 109f22ef01cSRoman Divacky return; 110f22ef01cSRoman Divacky } 111f22ef01cSRoman Divacky } 112f22ef01cSRoman Divacky 113f22ef01cSRoman Divacky // FIXME: We are at an unreachable point, there is no reason to emit the block 114f22ef01cSRoman Divacky // unless it has uses. However, we still need a place to put the debug 115f22ef01cSRoman Divacky // region.end for now. 116f22ef01cSRoman Divacky 117f22ef01cSRoman Divacky EmitBlock(ReturnBlock); 118f22ef01cSRoman Divacky } 119f22ef01cSRoman Divacky 120f22ef01cSRoman Divacky void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { 121f22ef01cSRoman Divacky assert(BreakContinueStack.empty() && 122f22ef01cSRoman Divacky "mismatched push/pop in break/continue stack!"); 123f22ef01cSRoman Divacky assert(BlockScopes.empty() && 124f22ef01cSRoman Divacky "did not remove all blocks from block scope map!"); 125f22ef01cSRoman Divacky assert(CleanupEntries.empty() && 126f22ef01cSRoman Divacky "mismatched push/pop in cleanup stack!"); 127f22ef01cSRoman Divacky 128f22ef01cSRoman Divacky // Emit function epilog (to return). 129f22ef01cSRoman Divacky EmitReturnBlock(); 130f22ef01cSRoman Divacky 131f22ef01cSRoman Divacky // Emit debug descriptor for function end. 132f22ef01cSRoman Divacky if (CGDebugInfo *DI = getDebugInfo()) { 133f22ef01cSRoman Divacky DI->setLocation(EndLoc); 134f22ef01cSRoman Divacky DI->EmitRegionEnd(CurFn, Builder); 135f22ef01cSRoman Divacky } 136f22ef01cSRoman Divacky 137f22ef01cSRoman Divacky EmitFunctionEpilog(*CurFnInfo, ReturnValue); 138f22ef01cSRoman Divacky EmitEndEHSpec(CurCodeDecl); 139f22ef01cSRoman Divacky 140f22ef01cSRoman Divacky // If someone did an indirect goto, emit the indirect goto block at the end of 141f22ef01cSRoman Divacky // the function. 142f22ef01cSRoman Divacky if (IndirectBranch) { 143f22ef01cSRoman Divacky EmitBlock(IndirectBranch->getParent()); 144f22ef01cSRoman Divacky Builder.ClearInsertionPoint(); 145f22ef01cSRoman Divacky } 146f22ef01cSRoman Divacky 147f22ef01cSRoman Divacky // Remove the AllocaInsertPt instruction, which is just a convenience for us. 148f22ef01cSRoman Divacky llvm::Instruction *Ptr = AllocaInsertPt; 149f22ef01cSRoman Divacky AllocaInsertPt = 0; 150f22ef01cSRoman Divacky Ptr->eraseFromParent(); 151f22ef01cSRoman Divacky 152f22ef01cSRoman Divacky // If someone took the address of a label but never did an indirect goto, we 153f22ef01cSRoman Divacky // made a zero entry PHI node, which is illegal, zap it now. 154f22ef01cSRoman Divacky if (IndirectBranch) { 155f22ef01cSRoman Divacky llvm::PHINode *PN = cast<llvm::PHINode>(IndirectBranch->getAddress()); 156f22ef01cSRoman Divacky if (PN->getNumIncomingValues() == 0) { 157f22ef01cSRoman Divacky PN->replaceAllUsesWith(llvm::UndefValue::get(PN->getType())); 158f22ef01cSRoman Divacky PN->eraseFromParent(); 159f22ef01cSRoman Divacky } 160f22ef01cSRoman Divacky } 161f22ef01cSRoman Divacky } 162f22ef01cSRoman Divacky 163f22ef01cSRoman Divacky void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, 164f22ef01cSRoman Divacky llvm::Function *Fn, 165f22ef01cSRoman Divacky const FunctionArgList &Args, 166f22ef01cSRoman Divacky SourceLocation StartLoc) { 167f22ef01cSRoman Divacky const Decl *D = GD.getDecl(); 168f22ef01cSRoman Divacky 169f22ef01cSRoman Divacky DidCallStackSave = false; 170f22ef01cSRoman Divacky CurCodeDecl = CurFuncDecl = D; 171f22ef01cSRoman Divacky FnRetTy = RetTy; 172f22ef01cSRoman Divacky CurFn = Fn; 173f22ef01cSRoman Divacky assert(CurFn->isDeclaration() && "Function already has body?"); 174f22ef01cSRoman Divacky 175f22ef01cSRoman Divacky // Pass inline keyword to optimizer if it appears explicitly on any 176f22ef01cSRoman Divacky // declaration. 177f22ef01cSRoman Divacky if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) 178f22ef01cSRoman Divacky for (FunctionDecl::redecl_iterator RI = FD->redecls_begin(), 179f22ef01cSRoman Divacky RE = FD->redecls_end(); RI != RE; ++RI) 180f22ef01cSRoman Divacky if (RI->isInlineSpecified()) { 181f22ef01cSRoman Divacky Fn->addFnAttr(llvm::Attribute::InlineHint); 182f22ef01cSRoman Divacky break; 183f22ef01cSRoman Divacky } 184f22ef01cSRoman Divacky 185f22ef01cSRoman Divacky llvm::BasicBlock *EntryBB = createBasicBlock("entry", CurFn); 186f22ef01cSRoman Divacky 187f22ef01cSRoman Divacky // Create a marker to make it easy to insert allocas into the entryblock 188f22ef01cSRoman Divacky // later. Don't create this with the builder, because we don't want it 189f22ef01cSRoman Divacky // folded. 190f22ef01cSRoman Divacky llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::getInt32Ty(VMContext)); 191f22ef01cSRoman Divacky AllocaInsertPt = new llvm::BitCastInst(Undef, 192f22ef01cSRoman Divacky llvm::Type::getInt32Ty(VMContext), "", 193f22ef01cSRoman Divacky EntryBB); 194f22ef01cSRoman Divacky if (Builder.isNamePreserving()) 195f22ef01cSRoman Divacky AllocaInsertPt->setName("allocapt"); 196f22ef01cSRoman Divacky 197f22ef01cSRoman Divacky ReturnBlock = createBasicBlock("return"); 198f22ef01cSRoman Divacky 199f22ef01cSRoman Divacky Builder.SetInsertPoint(EntryBB); 200f22ef01cSRoman Divacky 201f22ef01cSRoman Divacky QualType FnType = getContext().getFunctionType(RetTy, 0, 0, false, 0, 202f22ef01cSRoman Divacky false, false, 0, 0, 203f22ef01cSRoman Divacky /*FIXME?*/ 204f22ef01cSRoman Divacky FunctionType::ExtInfo()); 205f22ef01cSRoman Divacky 206f22ef01cSRoman Divacky // Emit subprogram debug descriptor. 207f22ef01cSRoman Divacky if (CGDebugInfo *DI = getDebugInfo()) { 208f22ef01cSRoman Divacky DI->setLocation(StartLoc); 209f22ef01cSRoman Divacky DI->EmitFunctionStart(GD, FnType, CurFn, Builder); 210f22ef01cSRoman Divacky } 211f22ef01cSRoman Divacky 212f22ef01cSRoman Divacky // FIXME: Leaked. 213f22ef01cSRoman Divacky // CC info is ignored, hopefully? 214f22ef01cSRoman Divacky CurFnInfo = &CGM.getTypes().getFunctionInfo(FnRetTy, Args, 215f22ef01cSRoman Divacky FunctionType::ExtInfo()); 216f22ef01cSRoman Divacky 217f22ef01cSRoman Divacky if (RetTy->isVoidType()) { 218f22ef01cSRoman Divacky // Void type; nothing to return. 219f22ef01cSRoman Divacky ReturnValue = 0; 220f22ef01cSRoman Divacky } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect && 221f22ef01cSRoman Divacky hasAggregateLLVMType(CurFnInfo->getReturnType())) { 222f22ef01cSRoman Divacky // Indirect aggregate return; emit returned value directly into sret slot. 223f22ef01cSRoman Divacky // This reduces code size, and affects correctness in C++. 224f22ef01cSRoman Divacky ReturnValue = CurFn->arg_begin(); 225f22ef01cSRoman Divacky } else { 226f22ef01cSRoman Divacky ReturnValue = CreateIRTemp(RetTy, "retval"); 227f22ef01cSRoman Divacky } 228f22ef01cSRoman Divacky 229f22ef01cSRoman Divacky EmitStartEHSpec(CurCodeDecl); 230f22ef01cSRoman Divacky EmitFunctionProlog(*CurFnInfo, CurFn, Args); 231f22ef01cSRoman Divacky 232f22ef01cSRoman Divacky if (CXXThisDecl) 233f22ef01cSRoman Divacky CXXThisValue = Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this"); 234f22ef01cSRoman Divacky if (CXXVTTDecl) 235f22ef01cSRoman Divacky CXXVTTValue = Builder.CreateLoad(LocalDeclMap[CXXVTTDecl], "vtt"); 236f22ef01cSRoman Divacky 237f22ef01cSRoman Divacky // If any of the arguments have a variably modified type, make sure to 238f22ef01cSRoman Divacky // emit the type size. 239f22ef01cSRoman Divacky for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); 240f22ef01cSRoman Divacky i != e; ++i) { 241f22ef01cSRoman Divacky QualType Ty = i->second; 242f22ef01cSRoman Divacky 243f22ef01cSRoman Divacky if (Ty->isVariablyModifiedType()) 244f22ef01cSRoman Divacky EmitVLASize(Ty); 245f22ef01cSRoman Divacky } 246f22ef01cSRoman Divacky } 247f22ef01cSRoman Divacky 248f22ef01cSRoman Divacky void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args) { 249f22ef01cSRoman Divacky const FunctionDecl *FD = cast<FunctionDecl>(CurGD.getDecl()); 250f22ef01cSRoman Divacky assert(FD->getBody()); 251f22ef01cSRoman Divacky EmitStmt(FD->getBody()); 252f22ef01cSRoman Divacky } 253f22ef01cSRoman Divacky 254f22ef01cSRoman Divacky void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn) { 255f22ef01cSRoman Divacky const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); 256f22ef01cSRoman Divacky 257f22ef01cSRoman Divacky // Check if we should generate debug info for this function. 258f22ef01cSRoman Divacky if (CGM.getDebugInfo() && !FD->hasAttr<NoDebugAttr>()) 259f22ef01cSRoman Divacky DebugInfo = CGM.getDebugInfo(); 260f22ef01cSRoman Divacky 261f22ef01cSRoman Divacky FunctionArgList Args; 262f22ef01cSRoman Divacky 263f22ef01cSRoman Divacky CurGD = GD; 264f22ef01cSRoman Divacky if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) { 265f22ef01cSRoman Divacky if (MD->isInstance()) { 266f22ef01cSRoman Divacky // Create the implicit 'this' decl. 267f22ef01cSRoman Divacky // FIXME: I'm not entirely sure I like using a fake decl just for code 268f22ef01cSRoman Divacky // generation. Maybe we can come up with a better way? 269f22ef01cSRoman Divacky CXXThisDecl = ImplicitParamDecl::Create(getContext(), 0, 270f22ef01cSRoman Divacky FD->getLocation(), 271f22ef01cSRoman Divacky &getContext().Idents.get("this"), 272f22ef01cSRoman Divacky MD->getThisType(getContext())); 273f22ef01cSRoman Divacky Args.push_back(std::make_pair(CXXThisDecl, CXXThisDecl->getType())); 274f22ef01cSRoman Divacky 275f22ef01cSRoman Divacky // Check if we need a VTT parameter as well. 276f22ef01cSRoman Divacky if (CodeGenVTables::needsVTTParameter(GD)) { 277f22ef01cSRoman Divacky // FIXME: The comment about using a fake decl above applies here too. 278f22ef01cSRoman Divacky QualType T = getContext().getPointerType(getContext().VoidPtrTy); 279f22ef01cSRoman Divacky CXXVTTDecl = 280f22ef01cSRoman Divacky ImplicitParamDecl::Create(getContext(), 0, FD->getLocation(), 281f22ef01cSRoman Divacky &getContext().Idents.get("vtt"), T); 282f22ef01cSRoman Divacky Args.push_back(std::make_pair(CXXVTTDecl, CXXVTTDecl->getType())); 283f22ef01cSRoman Divacky } 284f22ef01cSRoman Divacky } 285f22ef01cSRoman Divacky } 286f22ef01cSRoman Divacky 287f22ef01cSRoman Divacky if (FD->getNumParams()) { 288f22ef01cSRoman Divacky const FunctionProtoType* FProto = FD->getType()->getAs<FunctionProtoType>(); 289f22ef01cSRoman Divacky assert(FProto && "Function def must have prototype!"); 290f22ef01cSRoman Divacky 291f22ef01cSRoman Divacky for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) 292f22ef01cSRoman Divacky Args.push_back(std::make_pair(FD->getParamDecl(i), 293f22ef01cSRoman Divacky FProto->getArgType(i))); 294f22ef01cSRoman Divacky } 295f22ef01cSRoman Divacky 296f22ef01cSRoman Divacky SourceRange BodyRange; 297f22ef01cSRoman Divacky if (Stmt *Body = FD->getBody()) BodyRange = Body->getSourceRange(); 298f22ef01cSRoman Divacky 299f22ef01cSRoman Divacky // Emit the standard function prologue. 300f22ef01cSRoman Divacky StartFunction(GD, FD->getResultType(), Fn, Args, BodyRange.getBegin()); 301f22ef01cSRoman Divacky 302f22ef01cSRoman Divacky // Generate the body of the function. 303f22ef01cSRoman Divacky if (isa<CXXDestructorDecl>(FD)) 304f22ef01cSRoman Divacky EmitDestructorBody(Args); 305f22ef01cSRoman Divacky else if (isa<CXXConstructorDecl>(FD)) 306f22ef01cSRoman Divacky EmitConstructorBody(Args); 307f22ef01cSRoman Divacky else 308f22ef01cSRoman Divacky EmitFunctionBody(Args); 309f22ef01cSRoman Divacky 310f22ef01cSRoman Divacky // Emit the standard function epilogue. 311f22ef01cSRoman Divacky FinishFunction(BodyRange.getEnd()); 312f22ef01cSRoman Divacky 313f22ef01cSRoman Divacky // Destroy the 'this' declaration. 314f22ef01cSRoman Divacky if (CXXThisDecl) 315f22ef01cSRoman Divacky CXXThisDecl->Destroy(getContext()); 316f22ef01cSRoman Divacky 317f22ef01cSRoman Divacky // Destroy the VTT declaration. 318f22ef01cSRoman Divacky if (CXXVTTDecl) 319f22ef01cSRoman Divacky CXXVTTDecl->Destroy(getContext()); 320f22ef01cSRoman Divacky } 321f22ef01cSRoman Divacky 322f22ef01cSRoman Divacky /// ContainsLabel - Return true if the statement contains a label in it. If 323f22ef01cSRoman Divacky /// this statement is not executed normally, it not containing a label means 324f22ef01cSRoman Divacky /// that we can just remove the code. 325f22ef01cSRoman Divacky bool CodeGenFunction::ContainsLabel(const Stmt *S, bool IgnoreCaseStmts) { 326f22ef01cSRoman Divacky // Null statement, not a label! 327f22ef01cSRoman Divacky if (S == 0) return false; 328f22ef01cSRoman Divacky 329f22ef01cSRoman Divacky // If this is a label, we have to emit the code, consider something like: 330f22ef01cSRoman Divacky // if (0) { ... foo: bar(); } goto foo; 331f22ef01cSRoman Divacky if (isa<LabelStmt>(S)) 332f22ef01cSRoman Divacky return true; 333f22ef01cSRoman Divacky 334f22ef01cSRoman Divacky // If this is a case/default statement, and we haven't seen a switch, we have 335f22ef01cSRoman Divacky // to emit the code. 336f22ef01cSRoman Divacky if (isa<SwitchCase>(S) && !IgnoreCaseStmts) 337f22ef01cSRoman Divacky return true; 338f22ef01cSRoman Divacky 339f22ef01cSRoman Divacky // If this is a switch statement, we want to ignore cases below it. 340f22ef01cSRoman Divacky if (isa<SwitchStmt>(S)) 341f22ef01cSRoman Divacky IgnoreCaseStmts = true; 342f22ef01cSRoman Divacky 343f22ef01cSRoman Divacky // Scan subexpressions for verboten labels. 344f22ef01cSRoman Divacky for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end(); 345f22ef01cSRoman Divacky I != E; ++I) 346f22ef01cSRoman Divacky if (ContainsLabel(*I, IgnoreCaseStmts)) 347f22ef01cSRoman Divacky return true; 348f22ef01cSRoman Divacky 349f22ef01cSRoman Divacky return false; 350f22ef01cSRoman Divacky } 351f22ef01cSRoman Divacky 352f22ef01cSRoman Divacky 353f22ef01cSRoman Divacky /// ConstantFoldsToSimpleInteger - If the sepcified expression does not fold to 354f22ef01cSRoman Divacky /// a constant, or if it does but contains a label, return 0. If it constant 355f22ef01cSRoman Divacky /// folds to 'true' and does not contain a label, return 1, if it constant folds 356f22ef01cSRoman Divacky /// to 'false' and does not contain a label, return -1. 357f22ef01cSRoman Divacky int CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond) { 358f22ef01cSRoman Divacky // FIXME: Rename and handle conversion of other evaluatable things 359f22ef01cSRoman Divacky // to bool. 360f22ef01cSRoman Divacky Expr::EvalResult Result; 361f22ef01cSRoman Divacky if (!Cond->Evaluate(Result, getContext()) || !Result.Val.isInt() || 362f22ef01cSRoman Divacky Result.HasSideEffects) 363f22ef01cSRoman Divacky return 0; // Not foldable, not integer or not fully evaluatable. 364f22ef01cSRoman Divacky 365f22ef01cSRoman Divacky if (CodeGenFunction::ContainsLabel(Cond)) 366f22ef01cSRoman Divacky return 0; // Contains a label. 367f22ef01cSRoman Divacky 368f22ef01cSRoman Divacky return Result.Val.getInt().getBoolValue() ? 1 : -1; 369f22ef01cSRoman Divacky } 370f22ef01cSRoman Divacky 371f22ef01cSRoman Divacky 372f22ef01cSRoman Divacky /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an if 373f22ef01cSRoman Divacky /// statement) to the specified blocks. Based on the condition, this might try 374f22ef01cSRoman Divacky /// to simplify the codegen of the conditional based on the branch. 375f22ef01cSRoman Divacky /// 376f22ef01cSRoman Divacky void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, 377f22ef01cSRoman Divacky llvm::BasicBlock *TrueBlock, 378f22ef01cSRoman Divacky llvm::BasicBlock *FalseBlock) { 379f22ef01cSRoman Divacky if (const ParenExpr *PE = dyn_cast<ParenExpr>(Cond)) 380f22ef01cSRoman Divacky return EmitBranchOnBoolExpr(PE->getSubExpr(), TrueBlock, FalseBlock); 381f22ef01cSRoman Divacky 382f22ef01cSRoman Divacky if (const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) { 383f22ef01cSRoman Divacky // Handle X && Y in a condition. 384f22ef01cSRoman Divacky if (CondBOp->getOpcode() == BinaryOperator::LAnd) { 385f22ef01cSRoman Divacky // If we have "1 && X", simplify the code. "0 && X" would have constant 386f22ef01cSRoman Divacky // folded if the case was simple enough. 387f22ef01cSRoman Divacky if (ConstantFoldsToSimpleInteger(CondBOp->getLHS()) == 1) { 388f22ef01cSRoman Divacky // br(1 && X) -> br(X). 389f22ef01cSRoman Divacky return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock); 390f22ef01cSRoman Divacky } 391f22ef01cSRoman Divacky 392f22ef01cSRoman Divacky // If we have "X && 1", simplify the code to use an uncond branch. 393f22ef01cSRoman Divacky // "X && 0" would have been constant folded to 0. 394f22ef01cSRoman Divacky if (ConstantFoldsToSimpleInteger(CondBOp->getRHS()) == 1) { 395f22ef01cSRoman Divacky // br(X && 1) -> br(X). 396f22ef01cSRoman Divacky return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock); 397f22ef01cSRoman Divacky } 398f22ef01cSRoman Divacky 399f22ef01cSRoman Divacky // Emit the LHS as a conditional. If the LHS conditional is false, we 400f22ef01cSRoman Divacky // want to jump to the FalseBlock. 401f22ef01cSRoman Divacky llvm::BasicBlock *LHSTrue = createBasicBlock("land.lhs.true"); 402f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock); 403f22ef01cSRoman Divacky EmitBlock(LHSTrue); 404f22ef01cSRoman Divacky 405f22ef01cSRoman Divacky // Any temporaries created here are conditional. 406f22ef01cSRoman Divacky BeginConditionalBranch(); 407f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock); 408f22ef01cSRoman Divacky EndConditionalBranch(); 409f22ef01cSRoman Divacky 410f22ef01cSRoman Divacky return; 411f22ef01cSRoman Divacky } else if (CondBOp->getOpcode() == BinaryOperator::LOr) { 412f22ef01cSRoman Divacky // If we have "0 || X", simplify the code. "1 || X" would have constant 413f22ef01cSRoman Divacky // folded if the case was simple enough. 414f22ef01cSRoman Divacky if (ConstantFoldsToSimpleInteger(CondBOp->getLHS()) == -1) { 415f22ef01cSRoman Divacky // br(0 || X) -> br(X). 416f22ef01cSRoman Divacky return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock); 417f22ef01cSRoman Divacky } 418f22ef01cSRoman Divacky 419f22ef01cSRoman Divacky // If we have "X || 0", simplify the code to use an uncond branch. 420f22ef01cSRoman Divacky // "X || 1" would have been constant folded to 1. 421f22ef01cSRoman Divacky if (ConstantFoldsToSimpleInteger(CondBOp->getRHS()) == -1) { 422f22ef01cSRoman Divacky // br(X || 0) -> br(X). 423f22ef01cSRoman Divacky return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock); 424f22ef01cSRoman Divacky } 425f22ef01cSRoman Divacky 426f22ef01cSRoman Divacky // Emit the LHS as a conditional. If the LHS conditional is true, we 427f22ef01cSRoman Divacky // want to jump to the TrueBlock. 428f22ef01cSRoman Divacky llvm::BasicBlock *LHSFalse = createBasicBlock("lor.lhs.false"); 429f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse); 430f22ef01cSRoman Divacky EmitBlock(LHSFalse); 431f22ef01cSRoman Divacky 432f22ef01cSRoman Divacky // Any temporaries created here are conditional. 433f22ef01cSRoman Divacky BeginConditionalBranch(); 434f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock); 435f22ef01cSRoman Divacky EndConditionalBranch(); 436f22ef01cSRoman Divacky 437f22ef01cSRoman Divacky return; 438f22ef01cSRoman Divacky } 439f22ef01cSRoman Divacky } 440f22ef01cSRoman Divacky 441f22ef01cSRoman Divacky if (const UnaryOperator *CondUOp = dyn_cast<UnaryOperator>(Cond)) { 442f22ef01cSRoman Divacky // br(!x, t, f) -> br(x, f, t) 443f22ef01cSRoman Divacky if (CondUOp->getOpcode() == UnaryOperator::LNot) 444f22ef01cSRoman Divacky return EmitBranchOnBoolExpr(CondUOp->getSubExpr(), FalseBlock, TrueBlock); 445f22ef01cSRoman Divacky } 446f22ef01cSRoman Divacky 447f22ef01cSRoman Divacky if (const ConditionalOperator *CondOp = dyn_cast<ConditionalOperator>(Cond)) { 448f22ef01cSRoman Divacky // Handle ?: operator. 449f22ef01cSRoman Divacky 450f22ef01cSRoman Divacky // Just ignore GNU ?: extension. 451f22ef01cSRoman Divacky if (CondOp->getLHS()) { 452f22ef01cSRoman Divacky // br(c ? x : y, t, f) -> br(c, br(x, t, f), br(y, t, f)) 453f22ef01cSRoman Divacky llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true"); 454f22ef01cSRoman Divacky llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false"); 455f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondOp->getCond(), LHSBlock, RHSBlock); 456f22ef01cSRoman Divacky EmitBlock(LHSBlock); 457f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondOp->getLHS(), TrueBlock, FalseBlock); 458f22ef01cSRoman Divacky EmitBlock(RHSBlock); 459f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondOp->getRHS(), TrueBlock, FalseBlock); 460f22ef01cSRoman Divacky return; 461f22ef01cSRoman Divacky } 462f22ef01cSRoman Divacky } 463f22ef01cSRoman Divacky 464f22ef01cSRoman Divacky // Emit the code with the fully general case. 465f22ef01cSRoman Divacky llvm::Value *CondV = EvaluateExprAsBool(Cond); 466f22ef01cSRoman Divacky Builder.CreateCondBr(CondV, TrueBlock, FalseBlock); 467f22ef01cSRoman Divacky } 468f22ef01cSRoman Divacky 469f22ef01cSRoman Divacky /// ErrorUnsupported - Print out an error that codegen doesn't support the 470f22ef01cSRoman Divacky /// specified stmt yet. 471f22ef01cSRoman Divacky void CodeGenFunction::ErrorUnsupported(const Stmt *S, const char *Type, 472f22ef01cSRoman Divacky bool OmitOnError) { 473f22ef01cSRoman Divacky CGM.ErrorUnsupported(S, Type, OmitOnError); 474f22ef01cSRoman Divacky } 475f22ef01cSRoman Divacky 476f22ef01cSRoman Divacky void 477f22ef01cSRoman Divacky CodeGenFunction::EmitNullInitialization(llvm::Value *DestPtr, QualType Ty) { 478f22ef01cSRoman Divacky // If the type contains a pointer to data member we can't memset it to zero. 479f22ef01cSRoman Divacky // Instead, create a null constant and copy it to the destination. 480f22ef01cSRoman Divacky if (CGM.getTypes().ContainsPointerToDataMember(Ty)) { 481f22ef01cSRoman Divacky llvm::Constant *NullConstant = CGM.EmitNullConstant(Ty); 482f22ef01cSRoman Divacky 483f22ef01cSRoman Divacky llvm::GlobalVariable *NullVariable = 484f22ef01cSRoman Divacky new llvm::GlobalVariable(CGM.getModule(), NullConstant->getType(), 485f22ef01cSRoman Divacky /*isConstant=*/true, 486f22ef01cSRoman Divacky llvm::GlobalVariable::PrivateLinkage, 487f22ef01cSRoman Divacky NullConstant, llvm::Twine()); 488f22ef01cSRoman Divacky EmitAggregateCopy(DestPtr, NullVariable, Ty, /*isVolatile=*/false); 489f22ef01cSRoman Divacky return; 490f22ef01cSRoman Divacky } 491f22ef01cSRoman Divacky 492f22ef01cSRoman Divacky 493f22ef01cSRoman Divacky // Ignore empty classes in C++. 494f22ef01cSRoman Divacky if (getContext().getLangOptions().CPlusPlus) { 495f22ef01cSRoman Divacky if (const RecordType *RT = Ty->getAs<RecordType>()) { 496f22ef01cSRoman Divacky if (cast<CXXRecordDecl>(RT->getDecl())->isEmpty()) 497f22ef01cSRoman Divacky return; 498f22ef01cSRoman Divacky } 499f22ef01cSRoman Divacky } 500f22ef01cSRoman Divacky 501f22ef01cSRoman Divacky // Otherwise, just memset the whole thing to zero. This is legal 502f22ef01cSRoman Divacky // because in LLVM, all default initializers (other than the ones we just 503f22ef01cSRoman Divacky // handled above) are guaranteed to have a bit pattern of all zeros. 504f22ef01cSRoman Divacky const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext); 505f22ef01cSRoman Divacky if (DestPtr->getType() != BP) 506f22ef01cSRoman Divacky DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp"); 507f22ef01cSRoman Divacky 508f22ef01cSRoman Divacky // Get size and alignment info for this aggregate. 509f22ef01cSRoman Divacky std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty); 510f22ef01cSRoman Divacky 511f22ef01cSRoman Divacky // Don't bother emitting a zero-byte memset. 512f22ef01cSRoman Divacky if (TypeInfo.first == 0) 513f22ef01cSRoman Divacky return; 514f22ef01cSRoman Divacky 515f22ef01cSRoman Divacky // FIXME: Handle variable sized types. 516f22ef01cSRoman Divacky const llvm::Type *IntPtr = llvm::IntegerType::get(VMContext, 517f22ef01cSRoman Divacky LLVMPointerWidth); 518f22ef01cSRoman Divacky 519f22ef01cSRoman Divacky Builder.CreateCall5(CGM.getMemSetFn(BP, IntPtr), DestPtr, 520f22ef01cSRoman Divacky llvm::Constant::getNullValue(llvm::Type::getInt8Ty(VMContext)), 521f22ef01cSRoman Divacky // TypeInfo.first describes size in bits. 522f22ef01cSRoman Divacky llvm::ConstantInt::get(IntPtr, TypeInfo.first/8), 523f22ef01cSRoman Divacky llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 524f22ef01cSRoman Divacky TypeInfo.second/8), 525f22ef01cSRoman Divacky llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 526f22ef01cSRoman Divacky 0)); 527f22ef01cSRoman Divacky } 528f22ef01cSRoman Divacky 529f22ef01cSRoman Divacky llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelStmt *L) { 530f22ef01cSRoman Divacky // Make sure that there is a block for the indirect goto. 531f22ef01cSRoman Divacky if (IndirectBranch == 0) 532f22ef01cSRoman Divacky GetIndirectGotoBlock(); 533f22ef01cSRoman Divacky 534f22ef01cSRoman Divacky llvm::BasicBlock *BB = getBasicBlockForLabel(L); 535f22ef01cSRoman Divacky 536f22ef01cSRoman Divacky // Make sure the indirect branch includes all of the address-taken blocks. 537f22ef01cSRoman Divacky IndirectBranch->addDestination(BB); 538f22ef01cSRoman Divacky return llvm::BlockAddress::get(CurFn, BB); 539f22ef01cSRoman Divacky } 540f22ef01cSRoman Divacky 541f22ef01cSRoman Divacky llvm::BasicBlock *CodeGenFunction::GetIndirectGotoBlock() { 542f22ef01cSRoman Divacky // If we already made the indirect branch for indirect goto, return its block. 543f22ef01cSRoman Divacky if (IndirectBranch) return IndirectBranch->getParent(); 544f22ef01cSRoman Divacky 545f22ef01cSRoman Divacky CGBuilderTy TmpBuilder(createBasicBlock("indirectgoto")); 546f22ef01cSRoman Divacky 547f22ef01cSRoman Divacky const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); 548f22ef01cSRoman Divacky 549f22ef01cSRoman Divacky // Create the PHI node that indirect gotos will add entries to. 550f22ef01cSRoman Divacky llvm::Value *DestVal = TmpBuilder.CreatePHI(Int8PtrTy, "indirect.goto.dest"); 551f22ef01cSRoman Divacky 552f22ef01cSRoman Divacky // Create the indirect branch instruction. 553f22ef01cSRoman Divacky IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal); 554f22ef01cSRoman Divacky return IndirectBranch->getParent(); 555f22ef01cSRoman Divacky } 556f22ef01cSRoman Divacky 557f22ef01cSRoman Divacky llvm::Value *CodeGenFunction::GetVLASize(const VariableArrayType *VAT) { 558f22ef01cSRoman Divacky llvm::Value *&SizeEntry = VLASizeMap[VAT->getSizeExpr()]; 559f22ef01cSRoman Divacky 560f22ef01cSRoman Divacky assert(SizeEntry && "Did not emit size for type"); 561f22ef01cSRoman Divacky return SizeEntry; 562f22ef01cSRoman Divacky } 563f22ef01cSRoman Divacky 564f22ef01cSRoman Divacky llvm::Value *CodeGenFunction::EmitVLASize(QualType Ty) { 565f22ef01cSRoman Divacky assert(Ty->isVariablyModifiedType() && 566f22ef01cSRoman Divacky "Must pass variably modified type to EmitVLASizes!"); 567f22ef01cSRoman Divacky 568f22ef01cSRoman Divacky EnsureInsertPoint(); 569f22ef01cSRoman Divacky 570f22ef01cSRoman Divacky if (const VariableArrayType *VAT = getContext().getAsVariableArrayType(Ty)) { 571f22ef01cSRoman Divacky llvm::Value *&SizeEntry = VLASizeMap[VAT->getSizeExpr()]; 572f22ef01cSRoman Divacky 573f22ef01cSRoman Divacky if (!SizeEntry) { 574f22ef01cSRoman Divacky const llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 575f22ef01cSRoman Divacky 576f22ef01cSRoman Divacky // Get the element size; 577f22ef01cSRoman Divacky QualType ElemTy = VAT->getElementType(); 578f22ef01cSRoman Divacky llvm::Value *ElemSize; 579f22ef01cSRoman Divacky if (ElemTy->isVariableArrayType()) 580f22ef01cSRoman Divacky ElemSize = EmitVLASize(ElemTy); 581f22ef01cSRoman Divacky else 582f22ef01cSRoman Divacky ElemSize = llvm::ConstantInt::get(SizeTy, 583f22ef01cSRoman Divacky getContext().getTypeSizeInChars(ElemTy).getQuantity()); 584f22ef01cSRoman Divacky 585f22ef01cSRoman Divacky llvm::Value *NumElements = EmitScalarExpr(VAT->getSizeExpr()); 586f22ef01cSRoman Divacky NumElements = Builder.CreateIntCast(NumElements, SizeTy, false, "tmp"); 587f22ef01cSRoman Divacky 588f22ef01cSRoman Divacky SizeEntry = Builder.CreateMul(ElemSize, NumElements); 589f22ef01cSRoman Divacky } 590f22ef01cSRoman Divacky 591f22ef01cSRoman Divacky return SizeEntry; 592f22ef01cSRoman Divacky } 593f22ef01cSRoman Divacky 594f22ef01cSRoman Divacky if (const ArrayType *AT = dyn_cast<ArrayType>(Ty)) { 595f22ef01cSRoman Divacky EmitVLASize(AT->getElementType()); 596f22ef01cSRoman Divacky return 0; 597f22ef01cSRoman Divacky } 598f22ef01cSRoman Divacky 599f22ef01cSRoman Divacky const PointerType *PT = Ty->getAs<PointerType>(); 600f22ef01cSRoman Divacky assert(PT && "unknown VM type!"); 601f22ef01cSRoman Divacky EmitVLASize(PT->getPointeeType()); 602f22ef01cSRoman Divacky return 0; 603f22ef01cSRoman Divacky } 604f22ef01cSRoman Divacky 605f22ef01cSRoman Divacky llvm::Value* CodeGenFunction::EmitVAListRef(const Expr* E) { 606f22ef01cSRoman Divacky if (CGM.getContext().getBuiltinVaListType()->isArrayType()) { 607f22ef01cSRoman Divacky return EmitScalarExpr(E); 608f22ef01cSRoman Divacky } 609f22ef01cSRoman Divacky return EmitLValue(E).getAddress(); 610f22ef01cSRoman Divacky } 611f22ef01cSRoman Divacky 612f22ef01cSRoman Divacky void CodeGenFunction::PushCleanupBlock(llvm::BasicBlock *CleanupEntryBlock, 613f22ef01cSRoman Divacky llvm::BasicBlock *CleanupExitBlock, 614f22ef01cSRoman Divacky llvm::BasicBlock *PreviousInvokeDest, 615f22ef01cSRoman Divacky bool EHOnly) { 616f22ef01cSRoman Divacky CleanupEntries.push_back(CleanupEntry(CleanupEntryBlock, CleanupExitBlock, 617f22ef01cSRoman Divacky PreviousInvokeDest, EHOnly)); 618f22ef01cSRoman Divacky } 619f22ef01cSRoman Divacky 620f22ef01cSRoman Divacky void CodeGenFunction::EmitCleanupBlocks(size_t OldCleanupStackSize) { 621f22ef01cSRoman Divacky assert(CleanupEntries.size() >= OldCleanupStackSize && 622f22ef01cSRoman Divacky "Cleanup stack mismatch!"); 623f22ef01cSRoman Divacky 624f22ef01cSRoman Divacky while (CleanupEntries.size() > OldCleanupStackSize) 625f22ef01cSRoman Divacky EmitCleanupBlock(); 626f22ef01cSRoman Divacky } 627f22ef01cSRoman Divacky 628f22ef01cSRoman Divacky CodeGenFunction::CleanupBlockInfo CodeGenFunction::PopCleanupBlock() { 629f22ef01cSRoman Divacky CleanupEntry &CE = CleanupEntries.back(); 630f22ef01cSRoman Divacky 631f22ef01cSRoman Divacky llvm::BasicBlock *CleanupEntryBlock = CE.CleanupEntryBlock; 632f22ef01cSRoman Divacky 633f22ef01cSRoman Divacky std::vector<llvm::BasicBlock *> Blocks; 634f22ef01cSRoman Divacky std::swap(Blocks, CE.Blocks); 635f22ef01cSRoman Divacky 636f22ef01cSRoman Divacky std::vector<llvm::BranchInst *> BranchFixups; 637f22ef01cSRoman Divacky std::swap(BranchFixups, CE.BranchFixups); 638f22ef01cSRoman Divacky 639f22ef01cSRoman Divacky bool EHOnly = CE.EHOnly; 640f22ef01cSRoman Divacky 641f22ef01cSRoman Divacky setInvokeDest(CE.PreviousInvokeDest); 642f22ef01cSRoman Divacky 643f22ef01cSRoman Divacky CleanupEntries.pop_back(); 644f22ef01cSRoman Divacky 645f22ef01cSRoman Divacky // Check if any branch fixups pointed to the scope we just popped. If so, 646f22ef01cSRoman Divacky // we can remove them. 647f22ef01cSRoman Divacky for (size_t i = 0, e = BranchFixups.size(); i != e; ++i) { 648f22ef01cSRoman Divacky llvm::BasicBlock *Dest = BranchFixups[i]->getSuccessor(0); 649f22ef01cSRoman Divacky BlockScopeMap::iterator I = BlockScopes.find(Dest); 650f22ef01cSRoman Divacky 651f22ef01cSRoman Divacky if (I == BlockScopes.end()) 652f22ef01cSRoman Divacky continue; 653f22ef01cSRoman Divacky 654f22ef01cSRoman Divacky assert(I->second <= CleanupEntries.size() && "Invalid branch fixup!"); 655f22ef01cSRoman Divacky 656f22ef01cSRoman Divacky if (I->second == CleanupEntries.size()) { 657f22ef01cSRoman Divacky // We don't need to do this branch fixup. 658f22ef01cSRoman Divacky BranchFixups[i] = BranchFixups.back(); 659f22ef01cSRoman Divacky BranchFixups.pop_back(); 660f22ef01cSRoman Divacky i--; 661f22ef01cSRoman Divacky e--; 662f22ef01cSRoman Divacky continue; 663f22ef01cSRoman Divacky } 664f22ef01cSRoman Divacky } 665f22ef01cSRoman Divacky 666f22ef01cSRoman Divacky llvm::BasicBlock *SwitchBlock = CE.CleanupExitBlock; 667f22ef01cSRoman Divacky llvm::BasicBlock *EndBlock = 0; 668f22ef01cSRoman Divacky if (!BranchFixups.empty()) { 669f22ef01cSRoman Divacky if (!SwitchBlock) 670f22ef01cSRoman Divacky SwitchBlock = createBasicBlock("cleanup.switch"); 671f22ef01cSRoman Divacky EndBlock = createBasicBlock("cleanup.end"); 672f22ef01cSRoman Divacky 673f22ef01cSRoman Divacky llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); 674f22ef01cSRoman Divacky 675f22ef01cSRoman Divacky Builder.SetInsertPoint(SwitchBlock); 676f22ef01cSRoman Divacky 677f22ef01cSRoman Divacky llvm::Value *DestCodePtr 678f22ef01cSRoman Divacky = CreateTempAlloca(llvm::Type::getInt32Ty(VMContext), 679f22ef01cSRoman Divacky "cleanup.dst"); 680f22ef01cSRoman Divacky llvm::Value *DestCode = Builder.CreateLoad(DestCodePtr, "tmp"); 681f22ef01cSRoman Divacky 682f22ef01cSRoman Divacky // Create a switch instruction to determine where to jump next. 683f22ef01cSRoman Divacky llvm::SwitchInst *SI = Builder.CreateSwitch(DestCode, EndBlock, 684f22ef01cSRoman Divacky BranchFixups.size()); 685f22ef01cSRoman Divacky 686f22ef01cSRoman Divacky // Restore the current basic block (if any) 687f22ef01cSRoman Divacky if (CurBB) { 688f22ef01cSRoman Divacky Builder.SetInsertPoint(CurBB); 689f22ef01cSRoman Divacky 690f22ef01cSRoman Divacky // If we had a current basic block, we also need to emit an instruction 691f22ef01cSRoman Divacky // to initialize the cleanup destination. 692f22ef01cSRoman Divacky Builder.CreateStore(llvm::Constant::getNullValue(llvm::Type::getInt32Ty(VMContext)), 693f22ef01cSRoman Divacky DestCodePtr); 694f22ef01cSRoman Divacky } else 695f22ef01cSRoman Divacky Builder.ClearInsertionPoint(); 696f22ef01cSRoman Divacky 697f22ef01cSRoman Divacky for (size_t i = 0, e = BranchFixups.size(); i != e; ++i) { 698f22ef01cSRoman Divacky llvm::BranchInst *BI = BranchFixups[i]; 699f22ef01cSRoman Divacky llvm::BasicBlock *Dest = BI->getSuccessor(0); 700f22ef01cSRoman Divacky 701f22ef01cSRoman Divacky // Fixup the branch instruction to point to the cleanup block. 702f22ef01cSRoman Divacky BI->setSuccessor(0, CleanupEntryBlock); 703f22ef01cSRoman Divacky 704f22ef01cSRoman Divacky if (CleanupEntries.empty()) { 705f22ef01cSRoman Divacky llvm::ConstantInt *ID; 706f22ef01cSRoman Divacky 707f22ef01cSRoman Divacky // Check if we already have a destination for this block. 708f22ef01cSRoman Divacky if (Dest == SI->getDefaultDest()) 709f22ef01cSRoman Divacky ID = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0); 710f22ef01cSRoman Divacky else { 711f22ef01cSRoman Divacky ID = SI->findCaseDest(Dest); 712f22ef01cSRoman Divacky if (!ID) { 713f22ef01cSRoman Divacky // No code found, get a new unique one by using the number of 714f22ef01cSRoman Divacky // switch successors. 715f22ef01cSRoman Divacky ID = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 716f22ef01cSRoman Divacky SI->getNumSuccessors()); 717f22ef01cSRoman Divacky SI->addCase(ID, Dest); 718f22ef01cSRoman Divacky } 719f22ef01cSRoman Divacky } 720f22ef01cSRoman Divacky 721f22ef01cSRoman Divacky // Store the jump destination before the branch instruction. 722f22ef01cSRoman Divacky new llvm::StoreInst(ID, DestCodePtr, BI); 723f22ef01cSRoman Divacky } else { 724f22ef01cSRoman Divacky // We need to jump through another cleanup block. Create a pad block 725f22ef01cSRoman Divacky // with a branch instruction that jumps to the final destination and add 726f22ef01cSRoman Divacky // it as a branch fixup to the current cleanup scope. 727f22ef01cSRoman Divacky 728f22ef01cSRoman Divacky // Create the pad block. 729f22ef01cSRoman Divacky llvm::BasicBlock *CleanupPad = createBasicBlock("cleanup.pad", CurFn); 730f22ef01cSRoman Divacky 731f22ef01cSRoman Divacky // Create a unique case ID. 732f22ef01cSRoman Divacky llvm::ConstantInt *ID 733f22ef01cSRoman Divacky = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 734f22ef01cSRoman Divacky SI->getNumSuccessors()); 735f22ef01cSRoman Divacky 736f22ef01cSRoman Divacky // Store the jump destination before the branch instruction. 737f22ef01cSRoman Divacky new llvm::StoreInst(ID, DestCodePtr, BI); 738f22ef01cSRoman Divacky 739f22ef01cSRoman Divacky // Add it as the destination. 740f22ef01cSRoman Divacky SI->addCase(ID, CleanupPad); 741f22ef01cSRoman Divacky 742f22ef01cSRoman Divacky // Create the branch to the final destination. 743f22ef01cSRoman Divacky llvm::BranchInst *BI = llvm::BranchInst::Create(Dest); 744f22ef01cSRoman Divacky CleanupPad->getInstList().push_back(BI); 745f22ef01cSRoman Divacky 746f22ef01cSRoman Divacky // And add it as a branch fixup. 747f22ef01cSRoman Divacky CleanupEntries.back().BranchFixups.push_back(BI); 748f22ef01cSRoman Divacky } 749f22ef01cSRoman Divacky } 750f22ef01cSRoman Divacky } 751f22ef01cSRoman Divacky 752f22ef01cSRoman Divacky // Remove all blocks from the block scope map. 753f22ef01cSRoman Divacky for (size_t i = 0, e = Blocks.size(); i != e; ++i) { 754f22ef01cSRoman Divacky assert(BlockScopes.count(Blocks[i]) && 755f22ef01cSRoman Divacky "Did not find block in scope map!"); 756f22ef01cSRoman Divacky 757f22ef01cSRoman Divacky BlockScopes.erase(Blocks[i]); 758f22ef01cSRoman Divacky } 759f22ef01cSRoman Divacky 760f22ef01cSRoman Divacky return CleanupBlockInfo(CleanupEntryBlock, SwitchBlock, EndBlock, EHOnly); 761f22ef01cSRoman Divacky } 762f22ef01cSRoman Divacky 763f22ef01cSRoman Divacky void CodeGenFunction::EmitCleanupBlock() { 764f22ef01cSRoman Divacky CleanupBlockInfo Info = PopCleanupBlock(); 765f22ef01cSRoman Divacky 766f22ef01cSRoman Divacky if (Info.EHOnly) { 767f22ef01cSRoman Divacky // FIXME: Add this to the exceptional edge 768f22ef01cSRoman Divacky if (Info.CleanupBlock->getNumUses() == 0) 769f22ef01cSRoman Divacky delete Info.CleanupBlock; 770f22ef01cSRoman Divacky return; 771f22ef01cSRoman Divacky } 772f22ef01cSRoman Divacky 773f22ef01cSRoman Divacky // Scrub debug location info. 774f22ef01cSRoman Divacky for (llvm::BasicBlock::iterator LBI = Info.CleanupBlock->begin(), 775f22ef01cSRoman Divacky LBE = Info.CleanupBlock->end(); LBI != LBE; ++LBI) 776f22ef01cSRoman Divacky Builder.SetInstDebugLocation(LBI); 777f22ef01cSRoman Divacky 778f22ef01cSRoman Divacky llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); 779f22ef01cSRoman Divacky if (CurBB && !CurBB->getTerminator() && 780f22ef01cSRoman Divacky Info.CleanupBlock->getNumUses() == 0) { 781f22ef01cSRoman Divacky CurBB->getInstList().splice(CurBB->end(), Info.CleanupBlock->getInstList()); 782f22ef01cSRoman Divacky delete Info.CleanupBlock; 783f22ef01cSRoman Divacky } else 784f22ef01cSRoman Divacky EmitBlock(Info.CleanupBlock); 785f22ef01cSRoman Divacky 786f22ef01cSRoman Divacky if (Info.SwitchBlock) 787f22ef01cSRoman Divacky EmitBlock(Info.SwitchBlock); 788f22ef01cSRoman Divacky if (Info.EndBlock) 789f22ef01cSRoman Divacky EmitBlock(Info.EndBlock); 790f22ef01cSRoman Divacky } 791f22ef01cSRoman Divacky 792f22ef01cSRoman Divacky void CodeGenFunction::AddBranchFixup(llvm::BranchInst *BI) { 793f22ef01cSRoman Divacky assert(!CleanupEntries.empty() && 794f22ef01cSRoman Divacky "Trying to add branch fixup without cleanup block!"); 795f22ef01cSRoman Divacky 796f22ef01cSRoman Divacky // FIXME: We could be more clever here and check if there's already a branch 797f22ef01cSRoman Divacky // fixup for this destination and recycle it. 798f22ef01cSRoman Divacky CleanupEntries.back().BranchFixups.push_back(BI); 799f22ef01cSRoman Divacky } 800f22ef01cSRoman Divacky 801f22ef01cSRoman Divacky void CodeGenFunction::EmitBranchThroughCleanup(llvm::BasicBlock *Dest) { 802f22ef01cSRoman Divacky if (!HaveInsertPoint()) 803f22ef01cSRoman Divacky return; 804f22ef01cSRoman Divacky 805f22ef01cSRoman Divacky llvm::BranchInst* BI = Builder.CreateBr(Dest); 806f22ef01cSRoman Divacky 807f22ef01cSRoman Divacky Builder.ClearInsertionPoint(); 808f22ef01cSRoman Divacky 809f22ef01cSRoman Divacky // The stack is empty, no need to do any cleanup. 810f22ef01cSRoman Divacky if (CleanupEntries.empty()) 811f22ef01cSRoman Divacky return; 812f22ef01cSRoman Divacky 813f22ef01cSRoman Divacky if (!Dest->getParent()) { 814f22ef01cSRoman Divacky // We are trying to branch to a block that hasn't been inserted yet. 815f22ef01cSRoman Divacky AddBranchFixup(BI); 816f22ef01cSRoman Divacky return; 817f22ef01cSRoman Divacky } 818f22ef01cSRoman Divacky 819f22ef01cSRoman Divacky BlockScopeMap::iterator I = BlockScopes.find(Dest); 820f22ef01cSRoman Divacky if (I == BlockScopes.end()) { 821f22ef01cSRoman Divacky // We are trying to jump to a block that is outside of any cleanup scope. 822f22ef01cSRoman Divacky AddBranchFixup(BI); 823f22ef01cSRoman Divacky return; 824f22ef01cSRoman Divacky } 825f22ef01cSRoman Divacky 826f22ef01cSRoman Divacky assert(I->second < CleanupEntries.size() && 827f22ef01cSRoman Divacky "Trying to branch into cleanup region"); 828f22ef01cSRoman Divacky 829f22ef01cSRoman Divacky if (I->second == CleanupEntries.size() - 1) { 830f22ef01cSRoman Divacky // We have a branch to a block in the same scope. 831f22ef01cSRoman Divacky return; 832f22ef01cSRoman Divacky } 833f22ef01cSRoman Divacky 834f22ef01cSRoman Divacky AddBranchFixup(BI); 835f22ef01cSRoman Divacky } 836