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" 17ffd1746dSEd Schouten #include "CGException.h" 18f22ef01cSRoman Divacky #include "clang/Basic/TargetInfo.h" 19f22ef01cSRoman Divacky #include "clang/AST/APValue.h" 20f22ef01cSRoman Divacky #include "clang/AST/ASTContext.h" 21f22ef01cSRoman Divacky #include "clang/AST/Decl.h" 22f22ef01cSRoman Divacky #include "clang/AST/DeclCXX.h" 23f22ef01cSRoman Divacky #include "clang/AST/StmtCXX.h" 24ffd1746dSEd Schouten #include "clang/Frontend/CodeGenOptions.h" 25f22ef01cSRoman Divacky #include "llvm/Target/TargetData.h" 26ffd1746dSEd Schouten #include "llvm/Intrinsics.h" 27f22ef01cSRoman Divacky using namespace clang; 28f22ef01cSRoman Divacky using namespace CodeGen; 29f22ef01cSRoman Divacky 30f22ef01cSRoman Divacky CodeGenFunction::CodeGenFunction(CodeGenModule &cgm) 31f22ef01cSRoman Divacky : BlockFunction(cgm, *this, Builder), CGM(cgm), 32f22ef01cSRoman Divacky Target(CGM.getContext().Target), 33f22ef01cSRoman Divacky Builder(cgm.getModule().getContext()), 34ffd1746dSEd Schouten ExceptionSlot(0), DebugInfo(0), IndirectBranch(0), 35f22ef01cSRoman Divacky SwitchInsn(0), CaseRangeBlock(0), InvokeDest(0), 36ffd1746dSEd Schouten DidCallStackSave(false), UnreachableBlock(0), 37f22ef01cSRoman Divacky CXXThisDecl(0), CXXThisValue(0), CXXVTTDecl(0), CXXVTTValue(0), 38ffd1746dSEd Schouten ConditionalBranchLevel(0), TerminateLandingPad(0), TerminateHandler(0), 39ffd1746dSEd Schouten TrapBB(0) { 40ffd1746dSEd Schouten 41ffd1746dSEd Schouten // Get some frequently used types. 42f22ef01cSRoman Divacky LLVMPointerWidth = Target.getPointerWidth(0); 43ffd1746dSEd Schouten llvm::LLVMContext &LLVMContext = CGM.getLLVMContext(); 44ffd1746dSEd Schouten IntPtrTy = llvm::IntegerType::get(LLVMContext, LLVMPointerWidth); 45ffd1746dSEd Schouten Int32Ty = llvm::Type::getInt32Ty(LLVMContext); 46ffd1746dSEd Schouten Int64Ty = llvm::Type::getInt64Ty(LLVMContext); 47ffd1746dSEd Schouten 48f22ef01cSRoman Divacky Exceptions = getContext().getLangOptions().Exceptions; 49f22ef01cSRoman Divacky CatchUndefined = getContext().getLangOptions().CatchUndefined; 50f22ef01cSRoman Divacky CGM.getMangleContext().startNewFunction(); 51f22ef01cSRoman Divacky } 52f22ef01cSRoman Divacky 53f22ef01cSRoman Divacky ASTContext &CodeGenFunction::getContext() const { 54f22ef01cSRoman Divacky return CGM.getContext(); 55f22ef01cSRoman Divacky } 56f22ef01cSRoman Divacky 57f22ef01cSRoman Divacky 58f22ef01cSRoman Divacky llvm::Value *CodeGenFunction::GetAddrOfLocalVar(const VarDecl *VD) { 59f22ef01cSRoman Divacky llvm::Value *Res = LocalDeclMap[VD]; 60f22ef01cSRoman Divacky assert(Res && "Invalid argument to GetAddrOfLocalVar(), no decl!"); 61f22ef01cSRoman Divacky return Res; 62f22ef01cSRoman Divacky } 63f22ef01cSRoman Divacky 64f22ef01cSRoman Divacky llvm::Constant * 65f22ef01cSRoman Divacky CodeGenFunction::GetAddrOfStaticLocalVar(const VarDecl *BVD) { 66f22ef01cSRoman Divacky return cast<llvm::Constant>(GetAddrOfLocalVar(BVD)); 67f22ef01cSRoman Divacky } 68f22ef01cSRoman Divacky 69f22ef01cSRoman Divacky const llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) { 70f22ef01cSRoman Divacky return CGM.getTypes().ConvertTypeForMem(T); 71f22ef01cSRoman Divacky } 72f22ef01cSRoman Divacky 73f22ef01cSRoman Divacky const llvm::Type *CodeGenFunction::ConvertType(QualType T) { 74f22ef01cSRoman Divacky return CGM.getTypes().ConvertType(T); 75f22ef01cSRoman Divacky } 76f22ef01cSRoman Divacky 77f22ef01cSRoman Divacky bool CodeGenFunction::hasAggregateLLVMType(QualType T) { 78f22ef01cSRoman Divacky return T->isRecordType() || T->isArrayType() || T->isAnyComplexType() || 79f22ef01cSRoman Divacky T->isMemberFunctionPointerType(); 80f22ef01cSRoman Divacky } 81f22ef01cSRoman Divacky 82f22ef01cSRoman Divacky void CodeGenFunction::EmitReturnBlock() { 83f22ef01cSRoman Divacky // For cleanliness, we try to avoid emitting the return block for 84f22ef01cSRoman Divacky // simple cases. 85f22ef01cSRoman Divacky llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); 86f22ef01cSRoman Divacky 87f22ef01cSRoman Divacky if (CurBB) { 88f22ef01cSRoman Divacky assert(!CurBB->getTerminator() && "Unexpected terminated block."); 89f22ef01cSRoman Divacky 90f22ef01cSRoman Divacky // We have a valid insert point, reuse it if it is empty or there are no 91f22ef01cSRoman Divacky // explicit jumps to the return block. 92ffd1746dSEd Schouten if (CurBB->empty() || ReturnBlock.Block->use_empty()) { 93ffd1746dSEd Schouten ReturnBlock.Block->replaceAllUsesWith(CurBB); 94ffd1746dSEd Schouten delete ReturnBlock.Block; 95f22ef01cSRoman Divacky } else 96ffd1746dSEd Schouten EmitBlock(ReturnBlock.Block); 97f22ef01cSRoman Divacky return; 98f22ef01cSRoman Divacky } 99f22ef01cSRoman Divacky 100f22ef01cSRoman Divacky // Otherwise, if the return block is the target of a single direct 101f22ef01cSRoman Divacky // branch then we can just put the code in that block instead. This 102f22ef01cSRoman Divacky // cleans up functions which started with a unified return block. 103ffd1746dSEd Schouten if (ReturnBlock.Block->hasOneUse()) { 104f22ef01cSRoman Divacky llvm::BranchInst *BI = 105ffd1746dSEd Schouten dyn_cast<llvm::BranchInst>(*ReturnBlock.Block->use_begin()); 106ffd1746dSEd Schouten if (BI && BI->isUnconditional() && 107ffd1746dSEd Schouten BI->getSuccessor(0) == ReturnBlock.Block) { 108f22ef01cSRoman Divacky // Reset insertion point and delete the branch. 109f22ef01cSRoman Divacky Builder.SetInsertPoint(BI->getParent()); 110f22ef01cSRoman Divacky BI->eraseFromParent(); 111ffd1746dSEd Schouten delete ReturnBlock.Block; 112f22ef01cSRoman Divacky return; 113f22ef01cSRoman Divacky } 114f22ef01cSRoman Divacky } 115f22ef01cSRoman Divacky 116f22ef01cSRoman Divacky // FIXME: We are at an unreachable point, there is no reason to emit the block 117f22ef01cSRoman Divacky // unless it has uses. However, we still need a place to put the debug 118f22ef01cSRoman Divacky // region.end for now. 119f22ef01cSRoman Divacky 120ffd1746dSEd Schouten EmitBlock(ReturnBlock.Block); 121ffd1746dSEd Schouten } 122ffd1746dSEd Schouten 123ffd1746dSEd Schouten static void EmitIfUsed(CodeGenFunction &CGF, llvm::BasicBlock *BB) { 124ffd1746dSEd Schouten if (!BB) return; 125ffd1746dSEd Schouten if (!BB->use_empty()) 126ffd1746dSEd Schouten return CGF.CurFn->getBasicBlockList().push_back(BB); 127ffd1746dSEd Schouten delete BB; 128f22ef01cSRoman Divacky } 129f22ef01cSRoman Divacky 130f22ef01cSRoman Divacky void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { 131f22ef01cSRoman Divacky assert(BreakContinueStack.empty() && 132f22ef01cSRoman Divacky "mismatched push/pop in break/continue stack!"); 133f22ef01cSRoman Divacky 134f22ef01cSRoman Divacky // Emit function epilog (to return). 135f22ef01cSRoman Divacky EmitReturnBlock(); 136f22ef01cSRoman Divacky 137ffd1746dSEd Schouten EmitFunctionInstrumentation("__cyg_profile_func_exit"); 138ffd1746dSEd Schouten 139f22ef01cSRoman Divacky // Emit debug descriptor for function end. 140f22ef01cSRoman Divacky if (CGDebugInfo *DI = getDebugInfo()) { 141f22ef01cSRoman Divacky DI->setLocation(EndLoc); 142f22ef01cSRoman Divacky DI->EmitRegionEnd(CurFn, Builder); 143f22ef01cSRoman Divacky } 144f22ef01cSRoman Divacky 145ffd1746dSEd Schouten EmitFunctionEpilog(*CurFnInfo); 146f22ef01cSRoman Divacky EmitEndEHSpec(CurCodeDecl); 147f22ef01cSRoman Divacky 148ffd1746dSEd Schouten assert(EHStack.empty() && 149ffd1746dSEd Schouten "did not remove all scopes from cleanup stack!"); 150ffd1746dSEd Schouten 151f22ef01cSRoman Divacky // If someone did an indirect goto, emit the indirect goto block at the end of 152f22ef01cSRoman Divacky // the function. 153f22ef01cSRoman Divacky if (IndirectBranch) { 154f22ef01cSRoman Divacky EmitBlock(IndirectBranch->getParent()); 155f22ef01cSRoman Divacky Builder.ClearInsertionPoint(); 156f22ef01cSRoman Divacky } 157f22ef01cSRoman Divacky 158f22ef01cSRoman Divacky // Remove the AllocaInsertPt instruction, which is just a convenience for us. 159f22ef01cSRoman Divacky llvm::Instruction *Ptr = AllocaInsertPt; 160f22ef01cSRoman Divacky AllocaInsertPt = 0; 161f22ef01cSRoman Divacky Ptr->eraseFromParent(); 162f22ef01cSRoman Divacky 163f22ef01cSRoman Divacky // If someone took the address of a label but never did an indirect goto, we 164f22ef01cSRoman Divacky // made a zero entry PHI node, which is illegal, zap it now. 165f22ef01cSRoman Divacky if (IndirectBranch) { 166f22ef01cSRoman Divacky llvm::PHINode *PN = cast<llvm::PHINode>(IndirectBranch->getAddress()); 167f22ef01cSRoman Divacky if (PN->getNumIncomingValues() == 0) { 168f22ef01cSRoman Divacky PN->replaceAllUsesWith(llvm::UndefValue::get(PN->getType())); 169f22ef01cSRoman Divacky PN->eraseFromParent(); 170f22ef01cSRoman Divacky } 171f22ef01cSRoman Divacky } 172ffd1746dSEd Schouten 173ffd1746dSEd Schouten EmitIfUsed(*this, TerminateLandingPad); 174ffd1746dSEd Schouten EmitIfUsed(*this, TerminateHandler); 175ffd1746dSEd Schouten EmitIfUsed(*this, UnreachableBlock); 176ffd1746dSEd Schouten 177ffd1746dSEd Schouten if (CGM.getCodeGenOpts().EmitDeclMetadata) 178ffd1746dSEd Schouten EmitDeclMetadata(); 179ffd1746dSEd Schouten } 180ffd1746dSEd Schouten 181ffd1746dSEd Schouten /// ShouldInstrumentFunction - Return true if the current function should be 182ffd1746dSEd Schouten /// instrumented with __cyg_profile_func_* calls 183ffd1746dSEd Schouten bool CodeGenFunction::ShouldInstrumentFunction() { 184ffd1746dSEd Schouten if (!CGM.getCodeGenOpts().InstrumentFunctions) 185ffd1746dSEd Schouten return false; 186ffd1746dSEd Schouten if (CurFuncDecl->hasAttr<NoInstrumentFunctionAttr>()) 187ffd1746dSEd Schouten return false; 188ffd1746dSEd Schouten return true; 189ffd1746dSEd Schouten } 190ffd1746dSEd Schouten 191ffd1746dSEd Schouten /// EmitFunctionInstrumentation - Emit LLVM code to call the specified 192ffd1746dSEd Schouten /// instrumentation function with the current function and the call site, if 193ffd1746dSEd Schouten /// function instrumentation is enabled. 194ffd1746dSEd Schouten void CodeGenFunction::EmitFunctionInstrumentation(const char *Fn) { 195ffd1746dSEd Schouten if (!ShouldInstrumentFunction()) 196ffd1746dSEd Schouten return; 197ffd1746dSEd Schouten 198ffd1746dSEd Schouten const llvm::PointerType *PointerTy; 199ffd1746dSEd Schouten const llvm::FunctionType *FunctionTy; 200ffd1746dSEd Schouten std::vector<const llvm::Type*> ProfileFuncArgs; 201ffd1746dSEd Schouten 202ffd1746dSEd Schouten // void __cyg_profile_func_{enter,exit} (void *this_fn, void *call_site); 203ffd1746dSEd Schouten PointerTy = llvm::Type::getInt8PtrTy(VMContext); 204ffd1746dSEd Schouten ProfileFuncArgs.push_back(PointerTy); 205ffd1746dSEd Schouten ProfileFuncArgs.push_back(PointerTy); 206ffd1746dSEd Schouten FunctionTy = llvm::FunctionType::get( 207ffd1746dSEd Schouten llvm::Type::getVoidTy(VMContext), 208ffd1746dSEd Schouten ProfileFuncArgs, false); 209ffd1746dSEd Schouten 210ffd1746dSEd Schouten llvm::Constant *F = CGM.CreateRuntimeFunction(FunctionTy, Fn); 211ffd1746dSEd Schouten llvm::CallInst *CallSite = Builder.CreateCall( 212ffd1746dSEd Schouten CGM.getIntrinsic(llvm::Intrinsic::returnaddress, 0, 0), 213ffd1746dSEd Schouten llvm::ConstantInt::get(Int32Ty, 0), 214ffd1746dSEd Schouten "callsite"); 215ffd1746dSEd Schouten 216ffd1746dSEd Schouten Builder.CreateCall2(F, 217ffd1746dSEd Schouten llvm::ConstantExpr::getBitCast(CurFn, PointerTy), 218ffd1746dSEd Schouten CallSite); 219f22ef01cSRoman Divacky } 220f22ef01cSRoman Divacky 221f22ef01cSRoman Divacky void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, 222f22ef01cSRoman Divacky llvm::Function *Fn, 223f22ef01cSRoman Divacky const FunctionArgList &Args, 224f22ef01cSRoman Divacky SourceLocation StartLoc) { 225f22ef01cSRoman Divacky const Decl *D = GD.getDecl(); 226f22ef01cSRoman Divacky 227f22ef01cSRoman Divacky DidCallStackSave = false; 228f22ef01cSRoman Divacky CurCodeDecl = CurFuncDecl = D; 229f22ef01cSRoman Divacky FnRetTy = RetTy; 230f22ef01cSRoman Divacky CurFn = Fn; 231f22ef01cSRoman Divacky assert(CurFn->isDeclaration() && "Function already has body?"); 232f22ef01cSRoman Divacky 233f22ef01cSRoman Divacky // Pass inline keyword to optimizer if it appears explicitly on any 234f22ef01cSRoman Divacky // declaration. 235f22ef01cSRoman Divacky if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) 236f22ef01cSRoman Divacky for (FunctionDecl::redecl_iterator RI = FD->redecls_begin(), 237f22ef01cSRoman Divacky RE = FD->redecls_end(); RI != RE; ++RI) 238f22ef01cSRoman Divacky if (RI->isInlineSpecified()) { 239f22ef01cSRoman Divacky Fn->addFnAttr(llvm::Attribute::InlineHint); 240f22ef01cSRoman Divacky break; 241f22ef01cSRoman Divacky } 242f22ef01cSRoman Divacky 243f22ef01cSRoman Divacky llvm::BasicBlock *EntryBB = createBasicBlock("entry", CurFn); 244f22ef01cSRoman Divacky 245f22ef01cSRoman Divacky // Create a marker to make it easy to insert allocas into the entryblock 246f22ef01cSRoman Divacky // later. Don't create this with the builder, because we don't want it 247f22ef01cSRoman Divacky // folded. 248ffd1746dSEd Schouten llvm::Value *Undef = llvm::UndefValue::get(Int32Ty); 249ffd1746dSEd Schouten AllocaInsertPt = new llvm::BitCastInst(Undef, Int32Ty, "", EntryBB); 250f22ef01cSRoman Divacky if (Builder.isNamePreserving()) 251f22ef01cSRoman Divacky AllocaInsertPt->setName("allocapt"); 252f22ef01cSRoman Divacky 253ffd1746dSEd Schouten ReturnBlock = getJumpDestInCurrentScope("return"); 254f22ef01cSRoman Divacky 255f22ef01cSRoman Divacky Builder.SetInsertPoint(EntryBB); 256f22ef01cSRoman Divacky 257f22ef01cSRoman Divacky QualType FnType = getContext().getFunctionType(RetTy, 0, 0, false, 0, 258f22ef01cSRoman Divacky false, false, 0, 0, 259f22ef01cSRoman Divacky /*FIXME?*/ 260f22ef01cSRoman Divacky FunctionType::ExtInfo()); 261f22ef01cSRoman Divacky 262f22ef01cSRoman Divacky // Emit subprogram debug descriptor. 263f22ef01cSRoman Divacky if (CGDebugInfo *DI = getDebugInfo()) { 264f22ef01cSRoman Divacky DI->setLocation(StartLoc); 265f22ef01cSRoman Divacky DI->EmitFunctionStart(GD, FnType, CurFn, Builder); 266f22ef01cSRoman Divacky } 267f22ef01cSRoman Divacky 268ffd1746dSEd Schouten EmitFunctionInstrumentation("__cyg_profile_func_enter"); 269ffd1746dSEd Schouten 270f22ef01cSRoman Divacky // FIXME: Leaked. 271f22ef01cSRoman Divacky // CC info is ignored, hopefully? 272f22ef01cSRoman Divacky CurFnInfo = &CGM.getTypes().getFunctionInfo(FnRetTy, Args, 273f22ef01cSRoman Divacky FunctionType::ExtInfo()); 274f22ef01cSRoman Divacky 275f22ef01cSRoman Divacky if (RetTy->isVoidType()) { 276f22ef01cSRoman Divacky // Void type; nothing to return. 277f22ef01cSRoman Divacky ReturnValue = 0; 278f22ef01cSRoman Divacky } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect && 279f22ef01cSRoman Divacky hasAggregateLLVMType(CurFnInfo->getReturnType())) { 280f22ef01cSRoman Divacky // Indirect aggregate return; emit returned value directly into sret slot. 281f22ef01cSRoman Divacky // This reduces code size, and affects correctness in C++. 282f22ef01cSRoman Divacky ReturnValue = CurFn->arg_begin(); 283f22ef01cSRoman Divacky } else { 284f22ef01cSRoman Divacky ReturnValue = CreateIRTemp(RetTy, "retval"); 285f22ef01cSRoman Divacky } 286f22ef01cSRoman Divacky 287f22ef01cSRoman Divacky EmitStartEHSpec(CurCodeDecl); 288f22ef01cSRoman Divacky EmitFunctionProlog(*CurFnInfo, CurFn, Args); 289f22ef01cSRoman Divacky 290f22ef01cSRoman Divacky if (CXXThisDecl) 291f22ef01cSRoman Divacky CXXThisValue = Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this"); 292f22ef01cSRoman Divacky if (CXXVTTDecl) 293f22ef01cSRoman Divacky CXXVTTValue = Builder.CreateLoad(LocalDeclMap[CXXVTTDecl], "vtt"); 294f22ef01cSRoman Divacky 295f22ef01cSRoman Divacky // If any of the arguments have a variably modified type, make sure to 296f22ef01cSRoman Divacky // emit the type size. 297f22ef01cSRoman Divacky for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); 298f22ef01cSRoman Divacky i != e; ++i) { 299f22ef01cSRoman Divacky QualType Ty = i->second; 300f22ef01cSRoman Divacky 301f22ef01cSRoman Divacky if (Ty->isVariablyModifiedType()) 302f22ef01cSRoman Divacky EmitVLASize(Ty); 303f22ef01cSRoman Divacky } 304f22ef01cSRoman Divacky } 305f22ef01cSRoman Divacky 306f22ef01cSRoman Divacky void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args) { 307f22ef01cSRoman Divacky const FunctionDecl *FD = cast<FunctionDecl>(CurGD.getDecl()); 308f22ef01cSRoman Divacky assert(FD->getBody()); 309f22ef01cSRoman Divacky EmitStmt(FD->getBody()); 310f22ef01cSRoman Divacky } 311f22ef01cSRoman Divacky 312f22ef01cSRoman Divacky void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn) { 313f22ef01cSRoman Divacky const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); 314f22ef01cSRoman Divacky 315f22ef01cSRoman Divacky // Check if we should generate debug info for this function. 316f22ef01cSRoman Divacky if (CGM.getDebugInfo() && !FD->hasAttr<NoDebugAttr>()) 317f22ef01cSRoman Divacky DebugInfo = CGM.getDebugInfo(); 318f22ef01cSRoman Divacky 319f22ef01cSRoman Divacky FunctionArgList Args; 320f22ef01cSRoman Divacky 321f22ef01cSRoman Divacky CurGD = GD; 322f22ef01cSRoman Divacky if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) { 323f22ef01cSRoman Divacky if (MD->isInstance()) { 324f22ef01cSRoman Divacky // Create the implicit 'this' decl. 325f22ef01cSRoman Divacky // FIXME: I'm not entirely sure I like using a fake decl just for code 326f22ef01cSRoman Divacky // generation. Maybe we can come up with a better way? 327f22ef01cSRoman Divacky CXXThisDecl = ImplicitParamDecl::Create(getContext(), 0, 328f22ef01cSRoman Divacky FD->getLocation(), 329f22ef01cSRoman Divacky &getContext().Idents.get("this"), 330f22ef01cSRoman Divacky MD->getThisType(getContext())); 331f22ef01cSRoman Divacky Args.push_back(std::make_pair(CXXThisDecl, CXXThisDecl->getType())); 332f22ef01cSRoman Divacky 333f22ef01cSRoman Divacky // Check if we need a VTT parameter as well. 334f22ef01cSRoman Divacky if (CodeGenVTables::needsVTTParameter(GD)) { 335f22ef01cSRoman Divacky // FIXME: The comment about using a fake decl above applies here too. 336f22ef01cSRoman Divacky QualType T = getContext().getPointerType(getContext().VoidPtrTy); 337f22ef01cSRoman Divacky CXXVTTDecl = 338f22ef01cSRoman Divacky ImplicitParamDecl::Create(getContext(), 0, FD->getLocation(), 339f22ef01cSRoman Divacky &getContext().Idents.get("vtt"), T); 340f22ef01cSRoman Divacky Args.push_back(std::make_pair(CXXVTTDecl, CXXVTTDecl->getType())); 341f22ef01cSRoman Divacky } 342f22ef01cSRoman Divacky } 343f22ef01cSRoman Divacky } 344f22ef01cSRoman Divacky 345f22ef01cSRoman Divacky if (FD->getNumParams()) { 346f22ef01cSRoman Divacky const FunctionProtoType* FProto = FD->getType()->getAs<FunctionProtoType>(); 347f22ef01cSRoman Divacky assert(FProto && "Function def must have prototype!"); 348f22ef01cSRoman Divacky 349f22ef01cSRoman Divacky for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) 350f22ef01cSRoman Divacky Args.push_back(std::make_pair(FD->getParamDecl(i), 351f22ef01cSRoman Divacky FProto->getArgType(i))); 352f22ef01cSRoman Divacky } 353f22ef01cSRoman Divacky 354f22ef01cSRoman Divacky SourceRange BodyRange; 355f22ef01cSRoman Divacky if (Stmt *Body = FD->getBody()) BodyRange = Body->getSourceRange(); 356f22ef01cSRoman Divacky 357f22ef01cSRoman Divacky // Emit the standard function prologue. 358f22ef01cSRoman Divacky StartFunction(GD, FD->getResultType(), Fn, Args, BodyRange.getBegin()); 359f22ef01cSRoman Divacky 360f22ef01cSRoman Divacky // Generate the body of the function. 361f22ef01cSRoman Divacky if (isa<CXXDestructorDecl>(FD)) 362f22ef01cSRoman Divacky EmitDestructorBody(Args); 363f22ef01cSRoman Divacky else if (isa<CXXConstructorDecl>(FD)) 364f22ef01cSRoman Divacky EmitConstructorBody(Args); 365f22ef01cSRoman Divacky else 366f22ef01cSRoman Divacky EmitFunctionBody(Args); 367f22ef01cSRoman Divacky 368f22ef01cSRoman Divacky // Emit the standard function epilogue. 369f22ef01cSRoman Divacky FinishFunction(BodyRange.getEnd()); 370f22ef01cSRoman Divacky 371f22ef01cSRoman Divacky // Destroy the 'this' declaration. 372f22ef01cSRoman Divacky if (CXXThisDecl) 373f22ef01cSRoman Divacky CXXThisDecl->Destroy(getContext()); 374f22ef01cSRoman Divacky 375f22ef01cSRoman Divacky // Destroy the VTT declaration. 376f22ef01cSRoman Divacky if (CXXVTTDecl) 377f22ef01cSRoman Divacky CXXVTTDecl->Destroy(getContext()); 378f22ef01cSRoman Divacky } 379f22ef01cSRoman Divacky 380f22ef01cSRoman Divacky /// ContainsLabel - Return true if the statement contains a label in it. If 381f22ef01cSRoman Divacky /// this statement is not executed normally, it not containing a label means 382f22ef01cSRoman Divacky /// that we can just remove the code. 383f22ef01cSRoman Divacky bool CodeGenFunction::ContainsLabel(const Stmt *S, bool IgnoreCaseStmts) { 384f22ef01cSRoman Divacky // Null statement, not a label! 385f22ef01cSRoman Divacky if (S == 0) return false; 386f22ef01cSRoman Divacky 387f22ef01cSRoman Divacky // If this is a label, we have to emit the code, consider something like: 388f22ef01cSRoman Divacky // if (0) { ... foo: bar(); } goto foo; 389f22ef01cSRoman Divacky if (isa<LabelStmt>(S)) 390f22ef01cSRoman Divacky return true; 391f22ef01cSRoman Divacky 392f22ef01cSRoman Divacky // If this is a case/default statement, and we haven't seen a switch, we have 393f22ef01cSRoman Divacky // to emit the code. 394f22ef01cSRoman Divacky if (isa<SwitchCase>(S) && !IgnoreCaseStmts) 395f22ef01cSRoman Divacky return true; 396f22ef01cSRoman Divacky 397f22ef01cSRoman Divacky // If this is a switch statement, we want to ignore cases below it. 398f22ef01cSRoman Divacky if (isa<SwitchStmt>(S)) 399f22ef01cSRoman Divacky IgnoreCaseStmts = true; 400f22ef01cSRoman Divacky 401f22ef01cSRoman Divacky // Scan subexpressions for verboten labels. 402f22ef01cSRoman Divacky for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end(); 403f22ef01cSRoman Divacky I != E; ++I) 404f22ef01cSRoman Divacky if (ContainsLabel(*I, IgnoreCaseStmts)) 405f22ef01cSRoman Divacky return true; 406f22ef01cSRoman Divacky 407f22ef01cSRoman Divacky return false; 408f22ef01cSRoman Divacky } 409f22ef01cSRoman Divacky 410f22ef01cSRoman Divacky 411f22ef01cSRoman Divacky /// ConstantFoldsToSimpleInteger - If the sepcified expression does not fold to 412f22ef01cSRoman Divacky /// a constant, or if it does but contains a label, return 0. If it constant 413f22ef01cSRoman Divacky /// folds to 'true' and does not contain a label, return 1, if it constant folds 414f22ef01cSRoman Divacky /// to 'false' and does not contain a label, return -1. 415f22ef01cSRoman Divacky int CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond) { 416f22ef01cSRoman Divacky // FIXME: Rename and handle conversion of other evaluatable things 417f22ef01cSRoman Divacky // to bool. 418f22ef01cSRoman Divacky Expr::EvalResult Result; 419f22ef01cSRoman Divacky if (!Cond->Evaluate(Result, getContext()) || !Result.Val.isInt() || 420f22ef01cSRoman Divacky Result.HasSideEffects) 421f22ef01cSRoman Divacky return 0; // Not foldable, not integer or not fully evaluatable. 422f22ef01cSRoman Divacky 423f22ef01cSRoman Divacky if (CodeGenFunction::ContainsLabel(Cond)) 424f22ef01cSRoman Divacky return 0; // Contains a label. 425f22ef01cSRoman Divacky 426f22ef01cSRoman Divacky return Result.Val.getInt().getBoolValue() ? 1 : -1; 427f22ef01cSRoman Divacky } 428f22ef01cSRoman Divacky 429f22ef01cSRoman Divacky 430f22ef01cSRoman Divacky /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an if 431f22ef01cSRoman Divacky /// statement) to the specified blocks. Based on the condition, this might try 432f22ef01cSRoman Divacky /// to simplify the codegen of the conditional based on the branch. 433f22ef01cSRoman Divacky /// 434f22ef01cSRoman Divacky void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, 435f22ef01cSRoman Divacky llvm::BasicBlock *TrueBlock, 436f22ef01cSRoman Divacky llvm::BasicBlock *FalseBlock) { 437f22ef01cSRoman Divacky if (const ParenExpr *PE = dyn_cast<ParenExpr>(Cond)) 438f22ef01cSRoman Divacky return EmitBranchOnBoolExpr(PE->getSubExpr(), TrueBlock, FalseBlock); 439f22ef01cSRoman Divacky 440f22ef01cSRoman Divacky if (const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) { 441f22ef01cSRoman Divacky // Handle X && Y in a condition. 442f22ef01cSRoman Divacky if (CondBOp->getOpcode() == BinaryOperator::LAnd) { 443f22ef01cSRoman Divacky // If we have "1 && X", simplify the code. "0 && X" would have constant 444f22ef01cSRoman Divacky // folded if the case was simple enough. 445f22ef01cSRoman Divacky if (ConstantFoldsToSimpleInteger(CondBOp->getLHS()) == 1) { 446f22ef01cSRoman Divacky // br(1 && X) -> br(X). 447f22ef01cSRoman Divacky return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock); 448f22ef01cSRoman Divacky } 449f22ef01cSRoman Divacky 450f22ef01cSRoman Divacky // If we have "X && 1", simplify the code to use an uncond branch. 451f22ef01cSRoman Divacky // "X && 0" would have been constant folded to 0. 452f22ef01cSRoman Divacky if (ConstantFoldsToSimpleInteger(CondBOp->getRHS()) == 1) { 453f22ef01cSRoman Divacky // br(X && 1) -> br(X). 454f22ef01cSRoman Divacky return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock); 455f22ef01cSRoman Divacky } 456f22ef01cSRoman Divacky 457f22ef01cSRoman Divacky // Emit the LHS as a conditional. If the LHS conditional is false, we 458f22ef01cSRoman Divacky // want to jump to the FalseBlock. 459f22ef01cSRoman Divacky llvm::BasicBlock *LHSTrue = createBasicBlock("land.lhs.true"); 460f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock); 461f22ef01cSRoman Divacky EmitBlock(LHSTrue); 462f22ef01cSRoman Divacky 463f22ef01cSRoman Divacky // Any temporaries created here are conditional. 464f22ef01cSRoman Divacky BeginConditionalBranch(); 465f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock); 466f22ef01cSRoman Divacky EndConditionalBranch(); 467f22ef01cSRoman Divacky 468f22ef01cSRoman Divacky return; 469f22ef01cSRoman Divacky } else if (CondBOp->getOpcode() == BinaryOperator::LOr) { 470f22ef01cSRoman Divacky // If we have "0 || X", simplify the code. "1 || X" would have constant 471f22ef01cSRoman Divacky // folded if the case was simple enough. 472f22ef01cSRoman Divacky if (ConstantFoldsToSimpleInteger(CondBOp->getLHS()) == -1) { 473f22ef01cSRoman Divacky // br(0 || X) -> br(X). 474f22ef01cSRoman Divacky return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock); 475f22ef01cSRoman Divacky } 476f22ef01cSRoman Divacky 477f22ef01cSRoman Divacky // If we have "X || 0", simplify the code to use an uncond branch. 478f22ef01cSRoman Divacky // "X || 1" would have been constant folded to 1. 479f22ef01cSRoman Divacky if (ConstantFoldsToSimpleInteger(CondBOp->getRHS()) == -1) { 480f22ef01cSRoman Divacky // br(X || 0) -> br(X). 481f22ef01cSRoman Divacky return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock); 482f22ef01cSRoman Divacky } 483f22ef01cSRoman Divacky 484f22ef01cSRoman Divacky // Emit the LHS as a conditional. If the LHS conditional is true, we 485f22ef01cSRoman Divacky // want to jump to the TrueBlock. 486f22ef01cSRoman Divacky llvm::BasicBlock *LHSFalse = createBasicBlock("lor.lhs.false"); 487f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse); 488f22ef01cSRoman Divacky EmitBlock(LHSFalse); 489f22ef01cSRoman Divacky 490f22ef01cSRoman Divacky // Any temporaries created here are conditional. 491f22ef01cSRoman Divacky BeginConditionalBranch(); 492f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock); 493f22ef01cSRoman Divacky EndConditionalBranch(); 494f22ef01cSRoman Divacky 495f22ef01cSRoman Divacky return; 496f22ef01cSRoman Divacky } 497f22ef01cSRoman Divacky } 498f22ef01cSRoman Divacky 499f22ef01cSRoman Divacky if (const UnaryOperator *CondUOp = dyn_cast<UnaryOperator>(Cond)) { 500f22ef01cSRoman Divacky // br(!x, t, f) -> br(x, f, t) 501f22ef01cSRoman Divacky if (CondUOp->getOpcode() == UnaryOperator::LNot) 502f22ef01cSRoman Divacky return EmitBranchOnBoolExpr(CondUOp->getSubExpr(), FalseBlock, TrueBlock); 503f22ef01cSRoman Divacky } 504f22ef01cSRoman Divacky 505f22ef01cSRoman Divacky if (const ConditionalOperator *CondOp = dyn_cast<ConditionalOperator>(Cond)) { 506f22ef01cSRoman Divacky // Handle ?: operator. 507f22ef01cSRoman Divacky 508f22ef01cSRoman Divacky // Just ignore GNU ?: extension. 509f22ef01cSRoman Divacky if (CondOp->getLHS()) { 510f22ef01cSRoman Divacky // br(c ? x : y, t, f) -> br(c, br(x, t, f), br(y, t, f)) 511f22ef01cSRoman Divacky llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true"); 512f22ef01cSRoman Divacky llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false"); 513f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondOp->getCond(), LHSBlock, RHSBlock); 514f22ef01cSRoman Divacky EmitBlock(LHSBlock); 515f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondOp->getLHS(), TrueBlock, FalseBlock); 516f22ef01cSRoman Divacky EmitBlock(RHSBlock); 517f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondOp->getRHS(), TrueBlock, FalseBlock); 518f22ef01cSRoman Divacky return; 519f22ef01cSRoman Divacky } 520f22ef01cSRoman Divacky } 521f22ef01cSRoman Divacky 522f22ef01cSRoman Divacky // Emit the code with the fully general case. 523f22ef01cSRoman Divacky llvm::Value *CondV = EvaluateExprAsBool(Cond); 524f22ef01cSRoman Divacky Builder.CreateCondBr(CondV, TrueBlock, FalseBlock); 525f22ef01cSRoman Divacky } 526f22ef01cSRoman Divacky 527f22ef01cSRoman Divacky /// ErrorUnsupported - Print out an error that codegen doesn't support the 528f22ef01cSRoman Divacky /// specified stmt yet. 529f22ef01cSRoman Divacky void CodeGenFunction::ErrorUnsupported(const Stmt *S, const char *Type, 530f22ef01cSRoman Divacky bool OmitOnError) { 531f22ef01cSRoman Divacky CGM.ErrorUnsupported(S, Type, OmitOnError); 532f22ef01cSRoman Divacky } 533f22ef01cSRoman Divacky 534f22ef01cSRoman Divacky void 535f22ef01cSRoman Divacky CodeGenFunction::EmitNullInitialization(llvm::Value *DestPtr, QualType Ty) { 536f22ef01cSRoman Divacky // If the type contains a pointer to data member we can't memset it to zero. 537f22ef01cSRoman Divacky // Instead, create a null constant and copy it to the destination. 538f22ef01cSRoman Divacky if (CGM.getTypes().ContainsPointerToDataMember(Ty)) { 539f22ef01cSRoman Divacky llvm::Constant *NullConstant = CGM.EmitNullConstant(Ty); 540f22ef01cSRoman Divacky 541f22ef01cSRoman Divacky llvm::GlobalVariable *NullVariable = 542f22ef01cSRoman Divacky new llvm::GlobalVariable(CGM.getModule(), NullConstant->getType(), 543f22ef01cSRoman Divacky /*isConstant=*/true, 544f22ef01cSRoman Divacky llvm::GlobalVariable::PrivateLinkage, 545f22ef01cSRoman Divacky NullConstant, llvm::Twine()); 546f22ef01cSRoman Divacky EmitAggregateCopy(DestPtr, NullVariable, Ty, /*isVolatile=*/false); 547f22ef01cSRoman Divacky return; 548f22ef01cSRoman Divacky } 549f22ef01cSRoman Divacky 550f22ef01cSRoman Divacky 551f22ef01cSRoman Divacky // Ignore empty classes in C++. 552f22ef01cSRoman Divacky if (getContext().getLangOptions().CPlusPlus) { 553f22ef01cSRoman Divacky if (const RecordType *RT = Ty->getAs<RecordType>()) { 554f22ef01cSRoman Divacky if (cast<CXXRecordDecl>(RT->getDecl())->isEmpty()) 555f22ef01cSRoman Divacky return; 556f22ef01cSRoman Divacky } 557f22ef01cSRoman Divacky } 558f22ef01cSRoman Divacky 559f22ef01cSRoman Divacky // Otherwise, just memset the whole thing to zero. This is legal 560f22ef01cSRoman Divacky // because in LLVM, all default initializers (other than the ones we just 561f22ef01cSRoman Divacky // handled above) are guaranteed to have a bit pattern of all zeros. 562f22ef01cSRoman Divacky const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext); 563f22ef01cSRoman Divacky if (DestPtr->getType() != BP) 564f22ef01cSRoman Divacky DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp"); 565f22ef01cSRoman Divacky 566f22ef01cSRoman Divacky // Get size and alignment info for this aggregate. 567f22ef01cSRoman Divacky std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty); 568f22ef01cSRoman Divacky 569f22ef01cSRoman Divacky // Don't bother emitting a zero-byte memset. 570f22ef01cSRoman Divacky if (TypeInfo.first == 0) 571f22ef01cSRoman Divacky return; 572f22ef01cSRoman Divacky 573f22ef01cSRoman Divacky // FIXME: Handle variable sized types. 574ffd1746dSEd Schouten Builder.CreateCall5(CGM.getMemSetFn(BP, IntPtrTy), DestPtr, 575f22ef01cSRoman Divacky llvm::Constant::getNullValue(llvm::Type::getInt8Ty(VMContext)), 576f22ef01cSRoman Divacky // TypeInfo.first describes size in bits. 577ffd1746dSEd Schouten llvm::ConstantInt::get(IntPtrTy, TypeInfo.first/8), 578ffd1746dSEd Schouten llvm::ConstantInt::get(Int32Ty, TypeInfo.second/8), 579f22ef01cSRoman Divacky llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 580f22ef01cSRoman Divacky 0)); 581f22ef01cSRoman Divacky } 582f22ef01cSRoman Divacky 583f22ef01cSRoman Divacky llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelStmt *L) { 584f22ef01cSRoman Divacky // Make sure that there is a block for the indirect goto. 585f22ef01cSRoman Divacky if (IndirectBranch == 0) 586f22ef01cSRoman Divacky GetIndirectGotoBlock(); 587f22ef01cSRoman Divacky 588ffd1746dSEd Schouten llvm::BasicBlock *BB = getJumpDestForLabel(L).Block; 589f22ef01cSRoman Divacky 590f22ef01cSRoman Divacky // Make sure the indirect branch includes all of the address-taken blocks. 591f22ef01cSRoman Divacky IndirectBranch->addDestination(BB); 592f22ef01cSRoman Divacky return llvm::BlockAddress::get(CurFn, BB); 593f22ef01cSRoman Divacky } 594f22ef01cSRoman Divacky 595f22ef01cSRoman Divacky llvm::BasicBlock *CodeGenFunction::GetIndirectGotoBlock() { 596f22ef01cSRoman Divacky // If we already made the indirect branch for indirect goto, return its block. 597f22ef01cSRoman Divacky if (IndirectBranch) return IndirectBranch->getParent(); 598f22ef01cSRoman Divacky 599f22ef01cSRoman Divacky CGBuilderTy TmpBuilder(createBasicBlock("indirectgoto")); 600f22ef01cSRoman Divacky 601f22ef01cSRoman Divacky const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); 602f22ef01cSRoman Divacky 603f22ef01cSRoman Divacky // Create the PHI node that indirect gotos will add entries to. 604f22ef01cSRoman Divacky llvm::Value *DestVal = TmpBuilder.CreatePHI(Int8PtrTy, "indirect.goto.dest"); 605f22ef01cSRoman Divacky 606f22ef01cSRoman Divacky // Create the indirect branch instruction. 607f22ef01cSRoman Divacky IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal); 608f22ef01cSRoman Divacky return IndirectBranch->getParent(); 609f22ef01cSRoman Divacky } 610f22ef01cSRoman Divacky 611f22ef01cSRoman Divacky llvm::Value *CodeGenFunction::GetVLASize(const VariableArrayType *VAT) { 612f22ef01cSRoman Divacky llvm::Value *&SizeEntry = VLASizeMap[VAT->getSizeExpr()]; 613f22ef01cSRoman Divacky 614f22ef01cSRoman Divacky assert(SizeEntry && "Did not emit size for type"); 615f22ef01cSRoman Divacky return SizeEntry; 616f22ef01cSRoman Divacky } 617f22ef01cSRoman Divacky 618f22ef01cSRoman Divacky llvm::Value *CodeGenFunction::EmitVLASize(QualType Ty) { 619f22ef01cSRoman Divacky assert(Ty->isVariablyModifiedType() && 620f22ef01cSRoman Divacky "Must pass variably modified type to EmitVLASizes!"); 621f22ef01cSRoman Divacky 622f22ef01cSRoman Divacky EnsureInsertPoint(); 623f22ef01cSRoman Divacky 624f22ef01cSRoman Divacky if (const VariableArrayType *VAT = getContext().getAsVariableArrayType(Ty)) { 625f22ef01cSRoman Divacky llvm::Value *&SizeEntry = VLASizeMap[VAT->getSizeExpr()]; 626f22ef01cSRoman Divacky 627f22ef01cSRoman Divacky if (!SizeEntry) { 628f22ef01cSRoman Divacky const llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 629f22ef01cSRoman Divacky 630f22ef01cSRoman Divacky // Get the element size; 631f22ef01cSRoman Divacky QualType ElemTy = VAT->getElementType(); 632f22ef01cSRoman Divacky llvm::Value *ElemSize; 633f22ef01cSRoman Divacky if (ElemTy->isVariableArrayType()) 634f22ef01cSRoman Divacky ElemSize = EmitVLASize(ElemTy); 635f22ef01cSRoman Divacky else 636f22ef01cSRoman Divacky ElemSize = llvm::ConstantInt::get(SizeTy, 637f22ef01cSRoman Divacky getContext().getTypeSizeInChars(ElemTy).getQuantity()); 638f22ef01cSRoman Divacky 639f22ef01cSRoman Divacky llvm::Value *NumElements = EmitScalarExpr(VAT->getSizeExpr()); 640f22ef01cSRoman Divacky NumElements = Builder.CreateIntCast(NumElements, SizeTy, false, "tmp"); 641f22ef01cSRoman Divacky 642f22ef01cSRoman Divacky SizeEntry = Builder.CreateMul(ElemSize, NumElements); 643f22ef01cSRoman Divacky } 644f22ef01cSRoman Divacky 645f22ef01cSRoman Divacky return SizeEntry; 646f22ef01cSRoman Divacky } 647f22ef01cSRoman Divacky 648f22ef01cSRoman Divacky if (const ArrayType *AT = dyn_cast<ArrayType>(Ty)) { 649f22ef01cSRoman Divacky EmitVLASize(AT->getElementType()); 650f22ef01cSRoman Divacky return 0; 651f22ef01cSRoman Divacky } 652f22ef01cSRoman Divacky 653f22ef01cSRoman Divacky const PointerType *PT = Ty->getAs<PointerType>(); 654f22ef01cSRoman Divacky assert(PT && "unknown VM type!"); 655f22ef01cSRoman Divacky EmitVLASize(PT->getPointeeType()); 656f22ef01cSRoman Divacky return 0; 657f22ef01cSRoman Divacky } 658f22ef01cSRoman Divacky 659f22ef01cSRoman Divacky llvm::Value* CodeGenFunction::EmitVAListRef(const Expr* E) { 660ffd1746dSEd Schouten if (CGM.getContext().getBuiltinVaListType()->isArrayType()) 661f22ef01cSRoman Divacky return EmitScalarExpr(E); 662f22ef01cSRoman Divacky return EmitLValue(E).getAddress(); 663f22ef01cSRoman Divacky } 664f22ef01cSRoman Divacky 665ffd1746dSEd Schouten /// Pops cleanup blocks until the given savepoint is reached. 666ffd1746dSEd Schouten void CodeGenFunction::PopCleanupBlocks(EHScopeStack::stable_iterator Old) { 667ffd1746dSEd Schouten assert(Old.isValid()); 668ffd1746dSEd Schouten 669ffd1746dSEd Schouten EHScopeStack::iterator E = EHStack.find(Old); 670ffd1746dSEd Schouten while (EHStack.begin() != E) 671ffd1746dSEd Schouten PopCleanupBlock(); 672f22ef01cSRoman Divacky } 673f22ef01cSRoman Divacky 674ffd1746dSEd Schouten /// Destroys a cleanup if it was unused. 675ffd1746dSEd Schouten static void DestroyCleanup(CodeGenFunction &CGF, 676ffd1746dSEd Schouten llvm::BasicBlock *Entry, 677ffd1746dSEd Schouten llvm::BasicBlock *Exit) { 678ffd1746dSEd Schouten assert(Entry->use_empty() && "destroying cleanup with uses!"); 679ffd1746dSEd Schouten assert(Exit->getTerminator() == 0 && 680ffd1746dSEd Schouten "exit has terminator but entry has no predecessors!"); 681f22ef01cSRoman Divacky 682ffd1746dSEd Schouten // This doesn't always remove the entire cleanup, but it's much 683ffd1746dSEd Schouten // safer as long as we don't know what blocks belong to the cleanup. 684ffd1746dSEd Schouten // A *much* better approach if we care about this inefficiency would 685ffd1746dSEd Schouten // be to lazily emit the cleanup. 686ffd1746dSEd Schouten 687ffd1746dSEd Schouten // If the exit block is distinct from the entry, give it a branch to 688ffd1746dSEd Schouten // an unreachable destination. This preserves the well-formedness 689ffd1746dSEd Schouten // of the IR. 690ffd1746dSEd Schouten if (Entry != Exit) 691ffd1746dSEd Schouten llvm::BranchInst::Create(CGF.getUnreachableBlock(), Exit); 692ffd1746dSEd Schouten 693ffd1746dSEd Schouten assert(!Entry->getParent() && "cleanup entry already positioned?"); 694ffd1746dSEd Schouten // We can't just delete the entry; we have to kill any references to 695ffd1746dSEd Schouten // its instructions in other blocks. 696ffd1746dSEd Schouten for (llvm::BasicBlock::iterator I = Entry->begin(), E = Entry->end(); 697ffd1746dSEd Schouten I != E; ++I) 698ffd1746dSEd Schouten if (!I->use_empty()) 699ffd1746dSEd Schouten I->replaceAllUsesWith(llvm::UndefValue::get(I->getType())); 700ffd1746dSEd Schouten delete Entry; 701f22ef01cSRoman Divacky } 702f22ef01cSRoman Divacky 703ffd1746dSEd Schouten /// Creates a switch instruction to thread branches out of the given 704ffd1746dSEd Schouten /// block (which is the exit block of a cleanup). 705ffd1746dSEd Schouten static void CreateCleanupSwitch(CodeGenFunction &CGF, 706ffd1746dSEd Schouten llvm::BasicBlock *Block) { 707ffd1746dSEd Schouten if (Block->getTerminator()) { 708ffd1746dSEd Schouten assert(isa<llvm::SwitchInst>(Block->getTerminator()) && 709ffd1746dSEd Schouten "cleanup block already has a terminator, but it isn't a switch"); 710ffd1746dSEd Schouten return; 711f22ef01cSRoman Divacky } 712f22ef01cSRoman Divacky 713f22ef01cSRoman Divacky llvm::Value *DestCodePtr 714ffd1746dSEd Schouten = CGF.CreateTempAlloca(CGF.Builder.getInt32Ty(), "cleanup.dst"); 715ffd1746dSEd Schouten CGBuilderTy Builder(Block); 716f22ef01cSRoman Divacky llvm::Value *DestCode = Builder.CreateLoad(DestCodePtr, "tmp"); 717f22ef01cSRoman Divacky 718f22ef01cSRoman Divacky // Create a switch instruction to determine where to jump next. 719ffd1746dSEd Schouten Builder.CreateSwitch(DestCode, CGF.getUnreachableBlock()); 720f22ef01cSRoman Divacky } 721f22ef01cSRoman Divacky 722ffd1746dSEd Schouten /// Attempts to reduce a cleanup's entry block to a fallthrough. This 723ffd1746dSEd Schouten /// is basically llvm::MergeBlockIntoPredecessor, except 724ffd1746dSEd Schouten /// simplified/optimized for the tighter constraints on cleanup 725ffd1746dSEd Schouten /// blocks. 726ffd1746dSEd Schouten static void SimplifyCleanupEntry(CodeGenFunction &CGF, 727ffd1746dSEd Schouten llvm::BasicBlock *Entry) { 728ffd1746dSEd Schouten llvm::BasicBlock *Pred = Entry->getSinglePredecessor(); 729ffd1746dSEd Schouten if (!Pred) return; 730f22ef01cSRoman Divacky 731ffd1746dSEd Schouten llvm::BranchInst *Br = dyn_cast<llvm::BranchInst>(Pred->getTerminator()); 732ffd1746dSEd Schouten if (!Br || Br->isConditional()) return; 733ffd1746dSEd Schouten assert(Br->getSuccessor(0) == Entry); 734f22ef01cSRoman Divacky 735ffd1746dSEd Schouten // If we were previously inserting at the end of the cleanup entry 736ffd1746dSEd Schouten // block, we'll need to continue inserting at the end of the 737ffd1746dSEd Schouten // predecessor. 738ffd1746dSEd Schouten bool WasInsertBlock = CGF.Builder.GetInsertBlock() == Entry; 739ffd1746dSEd Schouten assert(!WasInsertBlock || CGF.Builder.GetInsertPoint() == Entry->end()); 740f22ef01cSRoman Divacky 741ffd1746dSEd Schouten // Kill the branch. 742ffd1746dSEd Schouten Br->eraseFromParent(); 743f22ef01cSRoman Divacky 744ffd1746dSEd Schouten // Merge the blocks. 745ffd1746dSEd Schouten Pred->getInstList().splice(Pred->end(), Entry->getInstList()); 746f22ef01cSRoman Divacky 747ffd1746dSEd Schouten // Kill the entry block. 748ffd1746dSEd Schouten Entry->eraseFromParent(); 749f22ef01cSRoman Divacky 750ffd1746dSEd Schouten if (WasInsertBlock) 751ffd1746dSEd Schouten CGF.Builder.SetInsertPoint(Pred); 752f22ef01cSRoman Divacky } 753f22ef01cSRoman Divacky 754ffd1746dSEd Schouten /// Attempts to reduce an cleanup's exit switch to an unconditional 755ffd1746dSEd Schouten /// branch. 756ffd1746dSEd Schouten static void SimplifyCleanupExit(llvm::BasicBlock *Exit) { 757ffd1746dSEd Schouten llvm::TerminatorInst *Terminator = Exit->getTerminator(); 758ffd1746dSEd Schouten assert(Terminator && "completed cleanup exit has no terminator"); 759f22ef01cSRoman Divacky 760ffd1746dSEd Schouten llvm::SwitchInst *Switch = dyn_cast<llvm::SwitchInst>(Terminator); 761ffd1746dSEd Schouten if (!Switch) return; 762ffd1746dSEd Schouten if (Switch->getNumCases() != 2) return; // default + 1 763ffd1746dSEd Schouten 764ffd1746dSEd Schouten llvm::LoadInst *Cond = cast<llvm::LoadInst>(Switch->getCondition()); 765ffd1746dSEd Schouten llvm::AllocaInst *CondVar = cast<llvm::AllocaInst>(Cond->getPointerOperand()); 766ffd1746dSEd Schouten 767ffd1746dSEd Schouten // Replace the switch instruction with an unconditional branch. 768ffd1746dSEd Schouten llvm::BasicBlock *Dest = Switch->getSuccessor(1); // default is 0 769ffd1746dSEd Schouten Switch->eraseFromParent(); 770ffd1746dSEd Schouten llvm::BranchInst::Create(Dest, Exit); 771ffd1746dSEd Schouten 772ffd1746dSEd Schouten // Delete all uses of the condition variable. 773ffd1746dSEd Schouten Cond->eraseFromParent(); 774ffd1746dSEd Schouten while (!CondVar->use_empty()) 775ffd1746dSEd Schouten cast<llvm::StoreInst>(*CondVar->use_begin())->eraseFromParent(); 776ffd1746dSEd Schouten 777ffd1746dSEd Schouten // Delete the condition variable itself. 778ffd1746dSEd Schouten CondVar->eraseFromParent(); 779f22ef01cSRoman Divacky } 780f22ef01cSRoman Divacky 781ffd1746dSEd Schouten /// Threads a branch fixup through a cleanup block. 782ffd1746dSEd Schouten static void ThreadFixupThroughCleanup(CodeGenFunction &CGF, 783ffd1746dSEd Schouten BranchFixup &Fixup, 784ffd1746dSEd Schouten llvm::BasicBlock *Entry, 785ffd1746dSEd Schouten llvm::BasicBlock *Exit) { 786ffd1746dSEd Schouten if (!Exit->getTerminator()) 787ffd1746dSEd Schouten CreateCleanupSwitch(CGF, Exit); 788ffd1746dSEd Schouten 789ffd1746dSEd Schouten // Find the switch and its destination index alloca. 790ffd1746dSEd Schouten llvm::SwitchInst *Switch = cast<llvm::SwitchInst>(Exit->getTerminator()); 791ffd1746dSEd Schouten llvm::Value *DestCodePtr = 792ffd1746dSEd Schouten cast<llvm::LoadInst>(Switch->getCondition())->getPointerOperand(); 793ffd1746dSEd Schouten 794ffd1746dSEd Schouten // Compute the index of the new case we're adding to the switch. 795ffd1746dSEd Schouten unsigned Index = Switch->getNumCases(); 796ffd1746dSEd Schouten 797ffd1746dSEd Schouten const llvm::IntegerType *i32 = llvm::Type::getInt32Ty(CGF.getLLVMContext()); 798ffd1746dSEd Schouten llvm::ConstantInt *IndexV = llvm::ConstantInt::get(i32, Index); 799ffd1746dSEd Schouten 800ffd1746dSEd Schouten // Set the index in the origin block. 801ffd1746dSEd Schouten new llvm::StoreInst(IndexV, DestCodePtr, Fixup.Origin); 802ffd1746dSEd Schouten 803ffd1746dSEd Schouten // Add a case to the switch. 804ffd1746dSEd Schouten Switch->addCase(IndexV, Fixup.Destination); 805ffd1746dSEd Schouten 806ffd1746dSEd Schouten // Change the last branch to point to the cleanup entry block. 807ffd1746dSEd Schouten Fixup.LatestBranch->setSuccessor(Fixup.LatestBranchIndex, Entry); 808ffd1746dSEd Schouten 809ffd1746dSEd Schouten // And finally, update the fixup. 810ffd1746dSEd Schouten Fixup.LatestBranch = Switch; 811ffd1746dSEd Schouten Fixup.LatestBranchIndex = Index; 812f22ef01cSRoman Divacky } 813f22ef01cSRoman Divacky 814ffd1746dSEd Schouten /// Try to simplify both the entry and exit edges of a cleanup. 815ffd1746dSEd Schouten static void SimplifyCleanupEdges(CodeGenFunction &CGF, 816ffd1746dSEd Schouten llvm::BasicBlock *Entry, 817ffd1746dSEd Schouten llvm::BasicBlock *Exit) { 818f22ef01cSRoman Divacky 819ffd1746dSEd Schouten // Given their current implementations, it's important to run these 820ffd1746dSEd Schouten // in this order: SimplifyCleanupEntry will delete Entry if it can 821ffd1746dSEd Schouten // be merged into its predecessor, which will then break 822ffd1746dSEd Schouten // SimplifyCleanupExit if (as is common) Entry == Exit. 823ffd1746dSEd Schouten 824ffd1746dSEd Schouten SimplifyCleanupExit(Exit); 825ffd1746dSEd Schouten SimplifyCleanupEntry(CGF, Entry); 826ffd1746dSEd Schouten } 827ffd1746dSEd Schouten 828ffd1746dSEd Schouten static void EmitLazyCleanup(CodeGenFunction &CGF, 829ffd1746dSEd Schouten EHScopeStack::LazyCleanup *Fn, 830ffd1746dSEd Schouten bool ForEH) { 831ffd1746dSEd Schouten if (ForEH) CGF.EHStack.pushTerminate(); 832ffd1746dSEd Schouten Fn->Emit(CGF, ForEH); 833ffd1746dSEd Schouten if (ForEH) CGF.EHStack.popTerminate(); 834ffd1746dSEd Schouten assert(CGF.HaveInsertPoint() && "cleanup ended with no insertion point?"); 835ffd1746dSEd Schouten } 836ffd1746dSEd Schouten 837ffd1746dSEd Schouten static void SplitAndEmitLazyCleanup(CodeGenFunction &CGF, 838ffd1746dSEd Schouten EHScopeStack::LazyCleanup *Fn, 839ffd1746dSEd Schouten bool ForEH, 840ffd1746dSEd Schouten llvm::BasicBlock *Entry) { 841ffd1746dSEd Schouten assert(Entry && "no entry block for cleanup"); 842ffd1746dSEd Schouten 843ffd1746dSEd Schouten // Remove the switch and load from the end of the entry block. 844ffd1746dSEd Schouten llvm::Instruction *Switch = &Entry->getInstList().back(); 845ffd1746dSEd Schouten Entry->getInstList().remove(Switch); 846ffd1746dSEd Schouten assert(isa<llvm::SwitchInst>(Switch)); 847ffd1746dSEd Schouten llvm::Instruction *Load = &Entry->getInstList().back(); 848ffd1746dSEd Schouten Entry->getInstList().remove(Load); 849ffd1746dSEd Schouten assert(isa<llvm::LoadInst>(Load)); 850ffd1746dSEd Schouten 851ffd1746dSEd Schouten assert(Entry->getInstList().empty() && 852ffd1746dSEd Schouten "lazy cleanup block not empty after removing load/switch pair?"); 853ffd1746dSEd Schouten 854ffd1746dSEd Schouten // Emit the actual cleanup at the end of the entry block. 855ffd1746dSEd Schouten CGF.Builder.SetInsertPoint(Entry); 856ffd1746dSEd Schouten EmitLazyCleanup(CGF, Fn, ForEH); 857ffd1746dSEd Schouten 858ffd1746dSEd Schouten // Put the load and switch at the end of the exit block. 859ffd1746dSEd Schouten llvm::BasicBlock *Exit = CGF.Builder.GetInsertBlock(); 860ffd1746dSEd Schouten Exit->getInstList().push_back(Load); 861ffd1746dSEd Schouten Exit->getInstList().push_back(Switch); 862ffd1746dSEd Schouten 863ffd1746dSEd Schouten // Clean up the edges if possible. 864ffd1746dSEd Schouten SimplifyCleanupEdges(CGF, Entry, Exit); 865ffd1746dSEd Schouten 866ffd1746dSEd Schouten CGF.Builder.ClearInsertionPoint(); 867ffd1746dSEd Schouten } 868ffd1746dSEd Schouten 869ffd1746dSEd Schouten static void PopLazyCleanupBlock(CodeGenFunction &CGF) { 870ffd1746dSEd Schouten assert(isa<EHLazyCleanupScope>(*CGF.EHStack.begin()) && "top not a cleanup!"); 871ffd1746dSEd Schouten EHLazyCleanupScope &Scope = cast<EHLazyCleanupScope>(*CGF.EHStack.begin()); 872ffd1746dSEd Schouten assert(Scope.getFixupDepth() <= CGF.EHStack.getNumBranchFixups()); 873ffd1746dSEd Schouten 874ffd1746dSEd Schouten // Check whether we need an EH cleanup. This is only true if we've 875ffd1746dSEd Schouten // generated a lazy EH cleanup block. 876ffd1746dSEd Schouten llvm::BasicBlock *EHEntry = Scope.getEHBlock(); 877ffd1746dSEd Schouten bool RequiresEHCleanup = (EHEntry != 0); 878ffd1746dSEd Schouten 879ffd1746dSEd Schouten // Check the three conditions which might require a normal cleanup: 880ffd1746dSEd Schouten 881ffd1746dSEd Schouten // - whether there are branch fix-ups through this cleanup 882ffd1746dSEd Schouten unsigned FixupDepth = Scope.getFixupDepth(); 883ffd1746dSEd Schouten bool HasFixups = CGF.EHStack.getNumBranchFixups() != FixupDepth; 884ffd1746dSEd Schouten 885ffd1746dSEd Schouten // - whether control has already been threaded through this cleanup 886ffd1746dSEd Schouten llvm::BasicBlock *NormalEntry = Scope.getNormalBlock(); 887ffd1746dSEd Schouten bool HasExistingBranches = (NormalEntry != 0); 888ffd1746dSEd Schouten 889ffd1746dSEd Schouten // - whether there's a fallthrough 890ffd1746dSEd Schouten llvm::BasicBlock *FallthroughSource = CGF.Builder.GetInsertBlock(); 891ffd1746dSEd Schouten bool HasFallthrough = (FallthroughSource != 0); 892ffd1746dSEd Schouten 893ffd1746dSEd Schouten bool RequiresNormalCleanup = false; 894ffd1746dSEd Schouten if (Scope.isNormalCleanup() && 895ffd1746dSEd Schouten (HasFixups || HasExistingBranches || HasFallthrough)) { 896ffd1746dSEd Schouten RequiresNormalCleanup = true; 897ffd1746dSEd Schouten } 898ffd1746dSEd Schouten 899ffd1746dSEd Schouten // If we don't need the cleanup at all, we're done. 900ffd1746dSEd Schouten if (!RequiresNormalCleanup && !RequiresEHCleanup) { 901ffd1746dSEd Schouten CGF.EHStack.popCleanup(); 902ffd1746dSEd Schouten assert(CGF.EHStack.getNumBranchFixups() == 0 || 903ffd1746dSEd Schouten CGF.EHStack.hasNormalCleanups()); 904f22ef01cSRoman Divacky return; 905f22ef01cSRoman Divacky } 906f22ef01cSRoman Divacky 907ffd1746dSEd Schouten // Copy the cleanup emission data out. Note that SmallVector 908ffd1746dSEd Schouten // guarantees maximal alignment for its buffer regardless of its 909ffd1746dSEd Schouten // type parameter. 910ffd1746dSEd Schouten llvm::SmallVector<char, 8*sizeof(void*)> CleanupBuffer; 911ffd1746dSEd Schouten CleanupBuffer.reserve(Scope.getCleanupSize()); 912ffd1746dSEd Schouten memcpy(CleanupBuffer.data(), 913ffd1746dSEd Schouten Scope.getCleanupBuffer(), Scope.getCleanupSize()); 914ffd1746dSEd Schouten CleanupBuffer.set_size(Scope.getCleanupSize()); 915ffd1746dSEd Schouten EHScopeStack::LazyCleanup *Fn = 916ffd1746dSEd Schouten reinterpret_cast<EHScopeStack::LazyCleanup*>(CleanupBuffer.data()); 917f22ef01cSRoman Divacky 918ffd1746dSEd Schouten // We're done with the scope; pop it off so we can emit the cleanups. 919ffd1746dSEd Schouten CGF.EHStack.popCleanup(); 920f22ef01cSRoman Divacky 921ffd1746dSEd Schouten if (RequiresNormalCleanup) { 922ffd1746dSEd Schouten // If we have a fallthrough and no other need for the cleanup, 923ffd1746dSEd Schouten // emit it directly. 924ffd1746dSEd Schouten if (HasFallthrough && !HasFixups && !HasExistingBranches) { 925ffd1746dSEd Schouten EmitLazyCleanup(CGF, Fn, /*ForEH*/ false); 926ffd1746dSEd Schouten 927ffd1746dSEd Schouten // Otherwise, the best approach is to thread everything through 928ffd1746dSEd Schouten // the cleanup block and then try to clean up after ourselves. 929ffd1746dSEd Schouten } else { 930ffd1746dSEd Schouten // Force the entry block to exist. 931ffd1746dSEd Schouten if (!HasExistingBranches) { 932ffd1746dSEd Schouten NormalEntry = CGF.createBasicBlock("cleanup"); 933ffd1746dSEd Schouten CreateCleanupSwitch(CGF, NormalEntry); 934f22ef01cSRoman Divacky } 935f22ef01cSRoman Divacky 936ffd1746dSEd Schouten CGF.EmitBlock(NormalEntry); 937f22ef01cSRoman Divacky 938ffd1746dSEd Schouten // Thread the fallthrough edge through the (momentarily trivial) 939ffd1746dSEd Schouten // cleanup. 940ffd1746dSEd Schouten llvm::BasicBlock *FallthroughDestination = 0; 941ffd1746dSEd Schouten if (HasFallthrough) { 942ffd1746dSEd Schouten assert(isa<llvm::BranchInst>(FallthroughSource->getTerminator())); 943ffd1746dSEd Schouten FallthroughDestination = CGF.createBasicBlock("cleanup.cont"); 944ffd1746dSEd Schouten 945ffd1746dSEd Schouten BranchFixup Fix; 946ffd1746dSEd Schouten Fix.Destination = FallthroughDestination; 947ffd1746dSEd Schouten Fix.LatestBranch = FallthroughSource->getTerminator(); 948ffd1746dSEd Schouten Fix.LatestBranchIndex = 0; 949ffd1746dSEd Schouten Fix.Origin = Fix.LatestBranch; 950ffd1746dSEd Schouten 951ffd1746dSEd Schouten // Restore fixup invariant. EmitBlock added a branch to the 952ffd1746dSEd Schouten // cleanup which we need to redirect to the destination. 953ffd1746dSEd Schouten cast<llvm::BranchInst>(Fix.LatestBranch) 954ffd1746dSEd Schouten ->setSuccessor(0, Fix.Destination); 955ffd1746dSEd Schouten 956ffd1746dSEd Schouten ThreadFixupThroughCleanup(CGF, Fix, NormalEntry, NormalEntry); 957f22ef01cSRoman Divacky } 958f22ef01cSRoman Divacky 959ffd1746dSEd Schouten // Thread any "real" fixups we need to thread. 960ffd1746dSEd Schouten for (unsigned I = FixupDepth, E = CGF.EHStack.getNumBranchFixups(); 961ffd1746dSEd Schouten I != E; ++I) 962ffd1746dSEd Schouten if (CGF.EHStack.getBranchFixup(I).Destination) 963ffd1746dSEd Schouten ThreadFixupThroughCleanup(CGF, CGF.EHStack.getBranchFixup(I), 964ffd1746dSEd Schouten NormalEntry, NormalEntry); 965ffd1746dSEd Schouten 966ffd1746dSEd Schouten SplitAndEmitLazyCleanup(CGF, Fn, /*ForEH*/ false, NormalEntry); 967ffd1746dSEd Schouten 968ffd1746dSEd Schouten if (HasFallthrough) 969ffd1746dSEd Schouten CGF.EmitBlock(FallthroughDestination); 970ffd1746dSEd Schouten } 971ffd1746dSEd Schouten } 972ffd1746dSEd Schouten 973ffd1746dSEd Schouten // Emit the EH cleanup if required. 974ffd1746dSEd Schouten if (RequiresEHCleanup) { 975ffd1746dSEd Schouten CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP(); 976ffd1746dSEd Schouten CGF.EmitBlock(EHEntry); 977ffd1746dSEd Schouten SplitAndEmitLazyCleanup(CGF, Fn, /*ForEH*/ true, EHEntry); 978ffd1746dSEd Schouten CGF.Builder.restoreIP(SavedIP); 979ffd1746dSEd Schouten } 980ffd1746dSEd Schouten } 981ffd1746dSEd Schouten 982ffd1746dSEd Schouten /// Pops a cleanup block. If the block includes a normal cleanup, the 983ffd1746dSEd Schouten /// current insertion point is threaded through the cleanup, as are 984ffd1746dSEd Schouten /// any branch fixups on the cleanup. 985ffd1746dSEd Schouten void CodeGenFunction::PopCleanupBlock() { 986ffd1746dSEd Schouten assert(!EHStack.empty() && "cleanup stack is empty!"); 987ffd1746dSEd Schouten if (isa<EHLazyCleanupScope>(*EHStack.begin())) 988ffd1746dSEd Schouten return PopLazyCleanupBlock(*this); 989ffd1746dSEd Schouten 990ffd1746dSEd Schouten assert(isa<EHCleanupScope>(*EHStack.begin()) && "top not a cleanup!"); 991ffd1746dSEd Schouten EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.begin()); 992ffd1746dSEd Schouten assert(Scope.getFixupDepth() <= EHStack.getNumBranchFixups()); 993ffd1746dSEd Schouten 994ffd1746dSEd Schouten // Handle the EH cleanup if (1) there is one and (2) it's different 995ffd1746dSEd Schouten // from the normal cleanup. 996ffd1746dSEd Schouten if (Scope.isEHCleanup() && 997ffd1746dSEd Schouten Scope.getEHEntry() != Scope.getNormalEntry()) { 998ffd1746dSEd Schouten llvm::BasicBlock *EHEntry = Scope.getEHEntry(); 999ffd1746dSEd Schouten llvm::BasicBlock *EHExit = Scope.getEHExit(); 1000ffd1746dSEd Schouten 1001ffd1746dSEd Schouten if (EHEntry->use_empty()) { 1002ffd1746dSEd Schouten DestroyCleanup(*this, EHEntry, EHExit); 1003ffd1746dSEd Schouten } else { 1004ffd1746dSEd Schouten // TODO: this isn't really the ideal location to put this EH 1005ffd1746dSEd Schouten // cleanup, but lazy emission is a better solution than trying 1006ffd1746dSEd Schouten // to pick a better spot. 1007ffd1746dSEd Schouten CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP(); 1008ffd1746dSEd Schouten EmitBlock(EHEntry); 1009ffd1746dSEd Schouten Builder.restoreIP(SavedIP); 1010ffd1746dSEd Schouten 1011ffd1746dSEd Schouten SimplifyCleanupEdges(*this, EHEntry, EHExit); 1012ffd1746dSEd Schouten } 1013ffd1746dSEd Schouten } 1014ffd1746dSEd Schouten 1015ffd1746dSEd Schouten // If we only have an EH cleanup, we don't really need to do much 1016ffd1746dSEd Schouten // here. Branch fixups just naturally drop down to the enclosing 1017ffd1746dSEd Schouten // cleanup scope. 1018ffd1746dSEd Schouten if (!Scope.isNormalCleanup()) { 1019ffd1746dSEd Schouten EHStack.popCleanup(); 1020ffd1746dSEd Schouten assert(EHStack.getNumBranchFixups() == 0 || EHStack.hasNormalCleanups()); 1021ffd1746dSEd Schouten return; 1022ffd1746dSEd Schouten } 1023ffd1746dSEd Schouten 1024ffd1746dSEd Schouten // Check whether the scope has any fixups that need to be threaded. 1025ffd1746dSEd Schouten unsigned FixupDepth = Scope.getFixupDepth(); 1026ffd1746dSEd Schouten bool HasFixups = EHStack.getNumBranchFixups() != FixupDepth; 1027ffd1746dSEd Schouten 1028ffd1746dSEd Schouten // Grab the entry and exit blocks. 1029ffd1746dSEd Schouten llvm::BasicBlock *Entry = Scope.getNormalEntry(); 1030ffd1746dSEd Schouten llvm::BasicBlock *Exit = Scope.getNormalExit(); 1031ffd1746dSEd Schouten 1032ffd1746dSEd Schouten // Check whether anything's been threaded through the cleanup already. 1033ffd1746dSEd Schouten assert((Exit->getTerminator() == 0) == Entry->use_empty() && 1034ffd1746dSEd Schouten "cleanup entry/exit mismatch"); 1035ffd1746dSEd Schouten bool HasExistingBranches = !Entry->use_empty(); 1036ffd1746dSEd Schouten 1037ffd1746dSEd Schouten // Check whether we need to emit a "fallthrough" branch through the 1038ffd1746dSEd Schouten // cleanup for the current insertion point. 1039ffd1746dSEd Schouten llvm::BasicBlock *FallThrough = Builder.GetInsertBlock(); 1040ffd1746dSEd Schouten if (FallThrough && FallThrough->getTerminator()) 1041ffd1746dSEd Schouten FallThrough = 0; 1042ffd1746dSEd Schouten 1043ffd1746dSEd Schouten // If *nothing* is using the cleanup, kill it. 1044ffd1746dSEd Schouten if (!FallThrough && !HasFixups && !HasExistingBranches) { 1045ffd1746dSEd Schouten EHStack.popCleanup(); 1046ffd1746dSEd Schouten DestroyCleanup(*this, Entry, Exit); 1047ffd1746dSEd Schouten return; 1048ffd1746dSEd Schouten } 1049ffd1746dSEd Schouten 1050ffd1746dSEd Schouten // Otherwise, add the block to the function. 1051ffd1746dSEd Schouten EmitBlock(Entry); 1052ffd1746dSEd Schouten 1053ffd1746dSEd Schouten if (FallThrough) 1054ffd1746dSEd Schouten Builder.SetInsertPoint(Exit); 1055ffd1746dSEd Schouten else 1056ffd1746dSEd Schouten Builder.ClearInsertionPoint(); 1057ffd1746dSEd Schouten 1058ffd1746dSEd Schouten // Fast case: if we don't have to add any fixups, and either 1059ffd1746dSEd Schouten // we don't have a fallthrough or the cleanup wasn't previously 1060ffd1746dSEd Schouten // used, then the setup above is sufficient. 1061ffd1746dSEd Schouten if (!HasFixups) { 1062ffd1746dSEd Schouten if (!FallThrough) { 1063ffd1746dSEd Schouten assert(HasExistingBranches && "no reason for cleanup but didn't kill before"); 1064ffd1746dSEd Schouten EHStack.popCleanup(); 1065ffd1746dSEd Schouten SimplifyCleanupEdges(*this, Entry, Exit); 1066ffd1746dSEd Schouten return; 1067ffd1746dSEd Schouten } else if (!HasExistingBranches) { 1068ffd1746dSEd Schouten assert(FallThrough && "no reason for cleanup but didn't kill before"); 1069ffd1746dSEd Schouten // We can't simplify the exit edge in this case because we're 1070ffd1746dSEd Schouten // already inserting at the end of the exit block. 1071ffd1746dSEd Schouten EHStack.popCleanup(); 1072ffd1746dSEd Schouten SimplifyCleanupEntry(*this, Entry); 1073ffd1746dSEd Schouten return; 1074ffd1746dSEd Schouten } 1075ffd1746dSEd Schouten } 1076ffd1746dSEd Schouten 1077ffd1746dSEd Schouten // Otherwise we're going to have to thread things through the cleanup. 1078ffd1746dSEd Schouten llvm::SmallVector<BranchFixup*, 8> Fixups; 1079ffd1746dSEd Schouten 1080ffd1746dSEd Schouten // Synthesize a fixup for the current insertion point. 1081ffd1746dSEd Schouten BranchFixup Cur; 1082ffd1746dSEd Schouten if (FallThrough) { 1083ffd1746dSEd Schouten Cur.Destination = createBasicBlock("cleanup.cont"); 1084ffd1746dSEd Schouten Cur.LatestBranch = FallThrough->getTerminator(); 1085ffd1746dSEd Schouten Cur.LatestBranchIndex = 0; 1086ffd1746dSEd Schouten Cur.Origin = Cur.LatestBranch; 1087ffd1746dSEd Schouten 1088ffd1746dSEd Schouten // Restore fixup invariant. EmitBlock added a branch to the cleanup 1089ffd1746dSEd Schouten // which we need to redirect to the destination. 1090ffd1746dSEd Schouten cast<llvm::BranchInst>(Cur.LatestBranch)->setSuccessor(0, Cur.Destination); 1091ffd1746dSEd Schouten 1092ffd1746dSEd Schouten Fixups.push_back(&Cur); 1093ffd1746dSEd Schouten } else { 1094ffd1746dSEd Schouten Cur.Destination = 0; 1095ffd1746dSEd Schouten } 1096ffd1746dSEd Schouten 1097ffd1746dSEd Schouten // Collect any "real" fixups we need to thread. 1098ffd1746dSEd Schouten for (unsigned I = FixupDepth, E = EHStack.getNumBranchFixups(); 1099ffd1746dSEd Schouten I != E; ++I) 1100ffd1746dSEd Schouten if (EHStack.getBranchFixup(I).Destination) 1101ffd1746dSEd Schouten Fixups.push_back(&EHStack.getBranchFixup(I)); 1102ffd1746dSEd Schouten 1103ffd1746dSEd Schouten assert(!Fixups.empty() && "no fixups, invariants broken!"); 1104ffd1746dSEd Schouten 1105ffd1746dSEd Schouten // If there's only a single fixup to thread through, do so with 1106ffd1746dSEd Schouten // unconditional branches. This only happens if there's a single 1107ffd1746dSEd Schouten // branch and no fallthrough. 1108ffd1746dSEd Schouten if (Fixups.size() == 1 && !HasExistingBranches) { 1109ffd1746dSEd Schouten Fixups[0]->LatestBranch->setSuccessor(Fixups[0]->LatestBranchIndex, Entry); 1110ffd1746dSEd Schouten llvm::BranchInst *Br = 1111ffd1746dSEd Schouten llvm::BranchInst::Create(Fixups[0]->Destination, Exit); 1112ffd1746dSEd Schouten Fixups[0]->LatestBranch = Br; 1113ffd1746dSEd Schouten Fixups[0]->LatestBranchIndex = 0; 1114ffd1746dSEd Schouten 1115ffd1746dSEd Schouten // Otherwise, force a switch statement and thread everything through 1116ffd1746dSEd Schouten // the switch. 1117ffd1746dSEd Schouten } else { 1118ffd1746dSEd Schouten CreateCleanupSwitch(*this, Exit); 1119ffd1746dSEd Schouten for (unsigned I = 0, E = Fixups.size(); I != E; ++I) 1120ffd1746dSEd Schouten ThreadFixupThroughCleanup(*this, *Fixups[I], Entry, Exit); 1121ffd1746dSEd Schouten } 1122ffd1746dSEd Schouten 1123ffd1746dSEd Schouten // Emit the fallthrough destination block if necessary. 1124ffd1746dSEd Schouten if (Cur.Destination) 1125ffd1746dSEd Schouten EmitBlock(Cur.Destination); 1126ffd1746dSEd Schouten 1127ffd1746dSEd Schouten // We're finally done with the cleanup. 1128ffd1746dSEd Schouten EHStack.popCleanup(); 1129ffd1746dSEd Schouten } 1130ffd1746dSEd Schouten 1131ffd1746dSEd Schouten void CodeGenFunction::EmitBranchThroughCleanup(JumpDest Dest) { 1132f22ef01cSRoman Divacky if (!HaveInsertPoint()) 1133f22ef01cSRoman Divacky return; 1134f22ef01cSRoman Divacky 1135ffd1746dSEd Schouten // Create the branch. 1136ffd1746dSEd Schouten llvm::BranchInst *BI = Builder.CreateBr(Dest.Block); 1137ffd1746dSEd Schouten 1138ffd1746dSEd Schouten // If we're not in a cleanup scope, we don't need to worry about 1139ffd1746dSEd Schouten // fixups. 1140ffd1746dSEd Schouten if (!EHStack.hasNormalCleanups()) { 1141ffd1746dSEd Schouten Builder.ClearInsertionPoint(); 1142ffd1746dSEd Schouten return; 1143ffd1746dSEd Schouten } 1144ffd1746dSEd Schouten 1145ffd1746dSEd Schouten // Initialize a fixup. 1146ffd1746dSEd Schouten BranchFixup Fixup; 1147ffd1746dSEd Schouten Fixup.Destination = Dest.Block; 1148ffd1746dSEd Schouten Fixup.Origin = BI; 1149ffd1746dSEd Schouten Fixup.LatestBranch = BI; 1150ffd1746dSEd Schouten Fixup.LatestBranchIndex = 0; 1151ffd1746dSEd Schouten 1152ffd1746dSEd Schouten // If we can't resolve the destination cleanup scope, just add this 1153ffd1746dSEd Schouten // to the current cleanup scope. 1154ffd1746dSEd Schouten if (!Dest.ScopeDepth.isValid()) { 1155ffd1746dSEd Schouten EHStack.addBranchFixup() = Fixup; 1156ffd1746dSEd Schouten Builder.ClearInsertionPoint(); 1157ffd1746dSEd Schouten return; 1158ffd1746dSEd Schouten } 1159ffd1746dSEd Schouten 1160ffd1746dSEd Schouten for (EHScopeStack::iterator I = EHStack.begin(), 1161ffd1746dSEd Schouten E = EHStack.find(Dest.ScopeDepth); I != E; ++I) { 1162ffd1746dSEd Schouten if (isa<EHCleanupScope>(*I)) { 1163ffd1746dSEd Schouten EHCleanupScope &Scope = cast<EHCleanupScope>(*I); 1164ffd1746dSEd Schouten if (Scope.isNormalCleanup()) 1165ffd1746dSEd Schouten ThreadFixupThroughCleanup(*this, Fixup, Scope.getNormalEntry(), 1166ffd1746dSEd Schouten Scope.getNormalExit()); 1167ffd1746dSEd Schouten } else if (isa<EHLazyCleanupScope>(*I)) { 1168ffd1746dSEd Schouten EHLazyCleanupScope &Scope = cast<EHLazyCleanupScope>(*I); 1169ffd1746dSEd Schouten if (Scope.isNormalCleanup()) { 1170ffd1746dSEd Schouten llvm::BasicBlock *Block = Scope.getNormalBlock(); 1171ffd1746dSEd Schouten if (!Block) { 1172ffd1746dSEd Schouten Block = createBasicBlock("cleanup"); 1173ffd1746dSEd Schouten Scope.setNormalBlock(Block); 1174ffd1746dSEd Schouten } 1175ffd1746dSEd Schouten ThreadFixupThroughCleanup(*this, Fixup, Block, Block); 1176ffd1746dSEd Schouten } 1177ffd1746dSEd Schouten } 1178ffd1746dSEd Schouten } 1179f22ef01cSRoman Divacky 1180f22ef01cSRoman Divacky Builder.ClearInsertionPoint(); 1181ffd1746dSEd Schouten } 1182f22ef01cSRoman Divacky 1183ffd1746dSEd Schouten void CodeGenFunction::EmitBranchThroughEHCleanup(JumpDest Dest) { 1184ffd1746dSEd Schouten if (!HaveInsertPoint()) 1185f22ef01cSRoman Divacky return; 1186f22ef01cSRoman Divacky 1187ffd1746dSEd Schouten // Create the branch. 1188ffd1746dSEd Schouten llvm::BranchInst *BI = Builder.CreateBr(Dest.Block); 1189ffd1746dSEd Schouten 1190ffd1746dSEd Schouten // If we're not in a cleanup scope, we don't need to worry about 1191ffd1746dSEd Schouten // fixups. 1192ffd1746dSEd Schouten if (!EHStack.hasEHCleanups()) { 1193ffd1746dSEd Schouten Builder.ClearInsertionPoint(); 1194f22ef01cSRoman Divacky return; 1195f22ef01cSRoman Divacky } 1196f22ef01cSRoman Divacky 1197ffd1746dSEd Schouten // Initialize a fixup. 1198ffd1746dSEd Schouten BranchFixup Fixup; 1199ffd1746dSEd Schouten Fixup.Destination = Dest.Block; 1200ffd1746dSEd Schouten Fixup.Origin = BI; 1201ffd1746dSEd Schouten Fixup.LatestBranch = BI; 1202ffd1746dSEd Schouten Fixup.LatestBranchIndex = 0; 1203ffd1746dSEd Schouten 1204ffd1746dSEd Schouten // We should never get invalid scope depths for these: invalid scope 1205ffd1746dSEd Schouten // depths only arise for as-yet-unemitted labels, and we can't do an 1206ffd1746dSEd Schouten // EH-unwind to one of those. 1207ffd1746dSEd Schouten assert(Dest.ScopeDepth.isValid() && "invalid scope depth on EH dest?"); 1208ffd1746dSEd Schouten 1209ffd1746dSEd Schouten for (EHScopeStack::iterator I = EHStack.begin(), 1210ffd1746dSEd Schouten E = EHStack.find(Dest.ScopeDepth); I != E; ++I) { 1211ffd1746dSEd Schouten if (isa<EHCleanupScope>(*I)) { 1212ffd1746dSEd Schouten EHCleanupScope &Scope = cast<EHCleanupScope>(*I); 1213ffd1746dSEd Schouten if (Scope.isEHCleanup()) 1214ffd1746dSEd Schouten ThreadFixupThroughCleanup(*this, Fixup, Scope.getEHEntry(), 1215ffd1746dSEd Schouten Scope.getEHExit()); 1216ffd1746dSEd Schouten } else if (isa<EHLazyCleanupScope>(*I)) { 1217ffd1746dSEd Schouten EHLazyCleanupScope &Scope = cast<EHLazyCleanupScope>(*I); 1218ffd1746dSEd Schouten if (Scope.isEHCleanup()) { 1219ffd1746dSEd Schouten llvm::BasicBlock *Block = Scope.getEHBlock(); 1220ffd1746dSEd Schouten if (!Block) { 1221ffd1746dSEd Schouten Block = createBasicBlock("eh.cleanup"); 1222ffd1746dSEd Schouten Scope.setEHBlock(Block); 1223ffd1746dSEd Schouten } 1224ffd1746dSEd Schouten ThreadFixupThroughCleanup(*this, Fixup, Block, Block); 1225ffd1746dSEd Schouten } 1226ffd1746dSEd Schouten } 1227f22ef01cSRoman Divacky } 1228f22ef01cSRoman Divacky 1229ffd1746dSEd Schouten Builder.ClearInsertionPoint(); 1230f22ef01cSRoman Divacky } 1231