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" 16e580952dSDimitry Andric #include "CGCXXABI.h" 17f22ef01cSRoman Divacky #include "CGDebugInfo.h" 18ffd1746dSEd Schouten #include "CGException.h" 19f22ef01cSRoman Divacky #include "clang/Basic/TargetInfo.h" 20f22ef01cSRoman Divacky #include "clang/AST/APValue.h" 21f22ef01cSRoman Divacky #include "clang/AST/ASTContext.h" 22f22ef01cSRoman Divacky #include "clang/AST/Decl.h" 23f22ef01cSRoman Divacky #include "clang/AST/DeclCXX.h" 24f22ef01cSRoman Divacky #include "clang/AST/StmtCXX.h" 25ffd1746dSEd Schouten #include "clang/Frontend/CodeGenOptions.h" 26f22ef01cSRoman Divacky #include "llvm/Target/TargetData.h" 27ffd1746dSEd Schouten #include "llvm/Intrinsics.h" 28f22ef01cSRoman Divacky using namespace clang; 29f22ef01cSRoman Divacky using namespace CodeGen; 30f22ef01cSRoman Divacky 31f22ef01cSRoman Divacky CodeGenFunction::CodeGenFunction(CodeGenModule &cgm) 322754fe60SDimitry Andric : CodeGenTypeCache(cgm), CGM(cgm), 332754fe60SDimitry Andric Target(CGM.getContext().Target), Builder(cgm.getModule().getContext()), 342754fe60SDimitry Andric BlockInfo(0), BlockPointer(0), 35e580952dSDimitry Andric NormalCleanupDest(0), EHCleanupDest(0), NextCleanupDestIndex(1), 36bd5abe19SDimitry Andric ExceptionSlot(0), EHSelectorSlot(0), 37bd5abe19SDimitry Andric DebugInfo(0), DisableDebugInfo(false), DidCallStackSave(false), 38bd5abe19SDimitry Andric IndirectBranch(0), SwitchInsn(0), CaseRangeBlock(0), UnreachableBlock(0), 39f22ef01cSRoman Divacky CXXThisDecl(0), CXXThisValue(0), CXXVTTDecl(0), CXXVTTValue(0), 402754fe60SDimitry Andric OutermostConditional(0), TerminateLandingPad(0), TerminateHandler(0), 41ffd1746dSEd Schouten TrapBB(0) { 42ffd1746dSEd Schouten 43f22ef01cSRoman Divacky CatchUndefined = getContext().getLangOptions().CatchUndefined; 44e580952dSDimitry Andric CGM.getCXXABI().getMangleContext().startNewFunction(); 45f22ef01cSRoman Divacky } 46f22ef01cSRoman Divacky 47f22ef01cSRoman Divacky 48f22ef01cSRoman Divacky const llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) { 49f22ef01cSRoman Divacky return CGM.getTypes().ConvertTypeForMem(T); 50f22ef01cSRoman Divacky } 51f22ef01cSRoman Divacky 52f22ef01cSRoman Divacky const llvm::Type *CodeGenFunction::ConvertType(QualType T) { 53f22ef01cSRoman Divacky return CGM.getTypes().ConvertType(T); 54f22ef01cSRoman Divacky } 55f22ef01cSRoman Divacky 56bd5abe19SDimitry Andric bool CodeGenFunction::hasAggregateLLVMType(QualType type) { 57bd5abe19SDimitry Andric switch (type.getCanonicalType()->getTypeClass()) { 58bd5abe19SDimitry Andric #define TYPE(name, parent) 59bd5abe19SDimitry Andric #define ABSTRACT_TYPE(name, parent) 60bd5abe19SDimitry Andric #define NON_CANONICAL_TYPE(name, parent) case Type::name: 61bd5abe19SDimitry Andric #define DEPENDENT_TYPE(name, parent) case Type::name: 62bd5abe19SDimitry Andric #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name: 63bd5abe19SDimitry Andric #include "clang/AST/TypeNodes.def" 64bd5abe19SDimitry Andric llvm_unreachable("non-canonical or dependent type in IR-generation"); 65bd5abe19SDimitry Andric 66bd5abe19SDimitry Andric case Type::Builtin: 67bd5abe19SDimitry Andric case Type::Pointer: 68bd5abe19SDimitry Andric case Type::BlockPointer: 69bd5abe19SDimitry Andric case Type::LValueReference: 70bd5abe19SDimitry Andric case Type::RValueReference: 71bd5abe19SDimitry Andric case Type::MemberPointer: 72bd5abe19SDimitry Andric case Type::Vector: 73bd5abe19SDimitry Andric case Type::ExtVector: 74bd5abe19SDimitry Andric case Type::FunctionProto: 75bd5abe19SDimitry Andric case Type::FunctionNoProto: 76bd5abe19SDimitry Andric case Type::Enum: 77bd5abe19SDimitry Andric case Type::ObjCObjectPointer: 78bd5abe19SDimitry Andric return false; 79bd5abe19SDimitry Andric 80bd5abe19SDimitry Andric // Complexes, arrays, records, and Objective-C objects. 81bd5abe19SDimitry Andric case Type::Complex: 82bd5abe19SDimitry Andric case Type::ConstantArray: 83bd5abe19SDimitry Andric case Type::IncompleteArray: 84bd5abe19SDimitry Andric case Type::VariableArray: 85bd5abe19SDimitry Andric case Type::Record: 86bd5abe19SDimitry Andric case Type::ObjCObject: 87bd5abe19SDimitry Andric case Type::ObjCInterface: 88bd5abe19SDimitry Andric return true; 89bd5abe19SDimitry Andric } 90bd5abe19SDimitry Andric llvm_unreachable("unknown type kind!"); 91f22ef01cSRoman Divacky } 92f22ef01cSRoman Divacky 93f22ef01cSRoman Divacky void CodeGenFunction::EmitReturnBlock() { 94f22ef01cSRoman Divacky // For cleanliness, we try to avoid emitting the return block for 95f22ef01cSRoman Divacky // simple cases. 96f22ef01cSRoman Divacky llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); 97f22ef01cSRoman Divacky 98f22ef01cSRoman Divacky if (CurBB) { 99f22ef01cSRoman Divacky assert(!CurBB->getTerminator() && "Unexpected terminated block."); 100f22ef01cSRoman Divacky 101f22ef01cSRoman Divacky // We have a valid insert point, reuse it if it is empty or there are no 102f22ef01cSRoman Divacky // explicit jumps to the return block. 103e580952dSDimitry Andric if (CurBB->empty() || ReturnBlock.getBlock()->use_empty()) { 104e580952dSDimitry Andric ReturnBlock.getBlock()->replaceAllUsesWith(CurBB); 105e580952dSDimitry Andric delete ReturnBlock.getBlock(); 106f22ef01cSRoman Divacky } else 107e580952dSDimitry Andric EmitBlock(ReturnBlock.getBlock()); 108f22ef01cSRoman Divacky return; 109f22ef01cSRoman Divacky } 110f22ef01cSRoman Divacky 111f22ef01cSRoman Divacky // Otherwise, if the return block is the target of a single direct 112f22ef01cSRoman Divacky // branch then we can just put the code in that block instead. This 113f22ef01cSRoman Divacky // cleans up functions which started with a unified return block. 114e580952dSDimitry Andric if (ReturnBlock.getBlock()->hasOneUse()) { 115f22ef01cSRoman Divacky llvm::BranchInst *BI = 116e580952dSDimitry Andric dyn_cast<llvm::BranchInst>(*ReturnBlock.getBlock()->use_begin()); 117ffd1746dSEd Schouten if (BI && BI->isUnconditional() && 118e580952dSDimitry Andric BI->getSuccessor(0) == ReturnBlock.getBlock()) { 119f22ef01cSRoman Divacky // Reset insertion point and delete the branch. 120f22ef01cSRoman Divacky Builder.SetInsertPoint(BI->getParent()); 121f22ef01cSRoman Divacky BI->eraseFromParent(); 122e580952dSDimitry Andric delete ReturnBlock.getBlock(); 123f22ef01cSRoman Divacky return; 124f22ef01cSRoman Divacky } 125f22ef01cSRoman Divacky } 126f22ef01cSRoman Divacky 127f22ef01cSRoman Divacky // FIXME: We are at an unreachable point, there is no reason to emit the block 128f22ef01cSRoman Divacky // unless it has uses. However, we still need a place to put the debug 129f22ef01cSRoman Divacky // region.end for now. 130f22ef01cSRoman Divacky 131e580952dSDimitry Andric EmitBlock(ReturnBlock.getBlock()); 132ffd1746dSEd Schouten } 133ffd1746dSEd Schouten 134ffd1746dSEd Schouten static void EmitIfUsed(CodeGenFunction &CGF, llvm::BasicBlock *BB) { 135ffd1746dSEd Schouten if (!BB) return; 136ffd1746dSEd Schouten if (!BB->use_empty()) 137ffd1746dSEd Schouten return CGF.CurFn->getBasicBlockList().push_back(BB); 138ffd1746dSEd Schouten delete BB; 139f22ef01cSRoman Divacky } 140f22ef01cSRoman Divacky 141f22ef01cSRoman Divacky void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { 142f22ef01cSRoman Divacky assert(BreakContinueStack.empty() && 143f22ef01cSRoman Divacky "mismatched push/pop in break/continue stack!"); 144f22ef01cSRoman Divacky 145f22ef01cSRoman Divacky // Emit function epilog (to return). 146f22ef01cSRoman Divacky EmitReturnBlock(); 147f22ef01cSRoman Divacky 1482754fe60SDimitry Andric if (ShouldInstrumentFunction()) 149ffd1746dSEd Schouten EmitFunctionInstrumentation("__cyg_profile_func_exit"); 150ffd1746dSEd Schouten 151f22ef01cSRoman Divacky // Emit debug descriptor for function end. 152f22ef01cSRoman Divacky if (CGDebugInfo *DI = getDebugInfo()) { 153f22ef01cSRoman Divacky DI->setLocation(EndLoc); 154e580952dSDimitry Andric DI->EmitFunctionEnd(Builder); 155f22ef01cSRoman Divacky } 156f22ef01cSRoman Divacky 157ffd1746dSEd Schouten EmitFunctionEpilog(*CurFnInfo); 158f22ef01cSRoman Divacky EmitEndEHSpec(CurCodeDecl); 159f22ef01cSRoman Divacky 160ffd1746dSEd Schouten assert(EHStack.empty() && 161ffd1746dSEd Schouten "did not remove all scopes from cleanup stack!"); 162ffd1746dSEd Schouten 163f22ef01cSRoman Divacky // If someone did an indirect goto, emit the indirect goto block at the end of 164f22ef01cSRoman Divacky // the function. 165f22ef01cSRoman Divacky if (IndirectBranch) { 166f22ef01cSRoman Divacky EmitBlock(IndirectBranch->getParent()); 167f22ef01cSRoman Divacky Builder.ClearInsertionPoint(); 168f22ef01cSRoman Divacky } 169f22ef01cSRoman Divacky 170f22ef01cSRoman Divacky // Remove the AllocaInsertPt instruction, which is just a convenience for us. 171f22ef01cSRoman Divacky llvm::Instruction *Ptr = AllocaInsertPt; 172f22ef01cSRoman Divacky AllocaInsertPt = 0; 173f22ef01cSRoman Divacky Ptr->eraseFromParent(); 174f22ef01cSRoman Divacky 175f22ef01cSRoman Divacky // If someone took the address of a label but never did an indirect goto, we 176f22ef01cSRoman Divacky // made a zero entry PHI node, which is illegal, zap it now. 177f22ef01cSRoman Divacky if (IndirectBranch) { 178f22ef01cSRoman Divacky llvm::PHINode *PN = cast<llvm::PHINode>(IndirectBranch->getAddress()); 179f22ef01cSRoman Divacky if (PN->getNumIncomingValues() == 0) { 180f22ef01cSRoman Divacky PN->replaceAllUsesWith(llvm::UndefValue::get(PN->getType())); 181f22ef01cSRoman Divacky PN->eraseFromParent(); 182f22ef01cSRoman Divacky } 183f22ef01cSRoman Divacky } 184ffd1746dSEd Schouten 185e580952dSDimitry Andric EmitIfUsed(*this, RethrowBlock.getBlock()); 186ffd1746dSEd Schouten EmitIfUsed(*this, TerminateLandingPad); 187ffd1746dSEd Schouten EmitIfUsed(*this, TerminateHandler); 188ffd1746dSEd Schouten EmitIfUsed(*this, UnreachableBlock); 189ffd1746dSEd Schouten 190ffd1746dSEd Schouten if (CGM.getCodeGenOpts().EmitDeclMetadata) 191ffd1746dSEd Schouten EmitDeclMetadata(); 192ffd1746dSEd Schouten } 193ffd1746dSEd Schouten 194ffd1746dSEd Schouten /// ShouldInstrumentFunction - Return true if the current function should be 195ffd1746dSEd Schouten /// instrumented with __cyg_profile_func_* calls 196ffd1746dSEd Schouten bool CodeGenFunction::ShouldInstrumentFunction() { 197ffd1746dSEd Schouten if (!CGM.getCodeGenOpts().InstrumentFunctions) 198ffd1746dSEd Schouten return false; 199bd5abe19SDimitry Andric if (!CurFuncDecl || CurFuncDecl->hasAttr<NoInstrumentFunctionAttr>()) 200ffd1746dSEd Schouten return false; 201ffd1746dSEd Schouten return true; 202ffd1746dSEd Schouten } 203ffd1746dSEd Schouten 204ffd1746dSEd Schouten /// EmitFunctionInstrumentation - Emit LLVM code to call the specified 205ffd1746dSEd Schouten /// instrumentation function with the current function and the call site, if 206ffd1746dSEd Schouten /// function instrumentation is enabled. 207ffd1746dSEd Schouten void CodeGenFunction::EmitFunctionInstrumentation(const char *Fn) { 208ffd1746dSEd Schouten // void __cyg_profile_func_{enter,exit} (void *this_fn, void *call_site); 209bd5abe19SDimitry Andric const llvm::PointerType *PointerTy = Int8PtrTy; 210bd5abe19SDimitry Andric const llvm::Type *ProfileFuncArgs[] = { PointerTy, PointerTy }; 211bd5abe19SDimitry Andric const llvm::FunctionType *FunctionTy = 212bd5abe19SDimitry Andric llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()), 213ffd1746dSEd Schouten ProfileFuncArgs, false); 214ffd1746dSEd Schouten 215ffd1746dSEd Schouten llvm::Constant *F = CGM.CreateRuntimeFunction(FunctionTy, Fn); 216ffd1746dSEd Schouten llvm::CallInst *CallSite = Builder.CreateCall( 217ffd1746dSEd Schouten CGM.getIntrinsic(llvm::Intrinsic::returnaddress, 0, 0), 218ffd1746dSEd Schouten llvm::ConstantInt::get(Int32Ty, 0), 219ffd1746dSEd Schouten "callsite"); 220ffd1746dSEd Schouten 221ffd1746dSEd Schouten Builder.CreateCall2(F, 222ffd1746dSEd Schouten llvm::ConstantExpr::getBitCast(CurFn, PointerTy), 223ffd1746dSEd Schouten CallSite); 224f22ef01cSRoman Divacky } 225f22ef01cSRoman Divacky 2262754fe60SDimitry Andric void CodeGenFunction::EmitMCountInstrumentation() { 2272754fe60SDimitry Andric llvm::FunctionType *FTy = 2282754fe60SDimitry Andric llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()), false); 2292754fe60SDimitry Andric 2302754fe60SDimitry Andric llvm::Constant *MCountFn = CGM.CreateRuntimeFunction(FTy, 2312754fe60SDimitry Andric Target.getMCountName()); 2322754fe60SDimitry Andric Builder.CreateCall(MCountFn); 2332754fe60SDimitry Andric } 2342754fe60SDimitry Andric 235f22ef01cSRoman Divacky void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, 236f22ef01cSRoman Divacky llvm::Function *Fn, 2373b0f4066SDimitry Andric const CGFunctionInfo &FnInfo, 238f22ef01cSRoman Divacky const FunctionArgList &Args, 239f22ef01cSRoman Divacky SourceLocation StartLoc) { 240f22ef01cSRoman Divacky const Decl *D = GD.getDecl(); 241f22ef01cSRoman Divacky 242f22ef01cSRoman Divacky DidCallStackSave = false; 243f22ef01cSRoman Divacky CurCodeDecl = CurFuncDecl = D; 244f22ef01cSRoman Divacky FnRetTy = RetTy; 245f22ef01cSRoman Divacky CurFn = Fn; 2463b0f4066SDimitry Andric CurFnInfo = &FnInfo; 247f22ef01cSRoman Divacky assert(CurFn->isDeclaration() && "Function already has body?"); 248f22ef01cSRoman Divacky 249f22ef01cSRoman Divacky // Pass inline keyword to optimizer if it appears explicitly on any 250f22ef01cSRoman Divacky // declaration. 251f22ef01cSRoman Divacky if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) 252f22ef01cSRoman Divacky for (FunctionDecl::redecl_iterator RI = FD->redecls_begin(), 253f22ef01cSRoman Divacky RE = FD->redecls_end(); RI != RE; ++RI) 254f22ef01cSRoman Divacky if (RI->isInlineSpecified()) { 255f22ef01cSRoman Divacky Fn->addFnAttr(llvm::Attribute::InlineHint); 256f22ef01cSRoman Divacky break; 257f22ef01cSRoman Divacky } 258f22ef01cSRoman Divacky 2592754fe60SDimitry Andric if (getContext().getLangOptions().OpenCL) { 2602754fe60SDimitry Andric // Add metadata for a kernel function. 2612754fe60SDimitry Andric if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) 2622754fe60SDimitry Andric if (FD->hasAttr<OpenCLKernelAttr>()) { 2632754fe60SDimitry Andric llvm::LLVMContext &Context = getLLVMContext(); 2642754fe60SDimitry Andric llvm::NamedMDNode *OpenCLMetadata = 2652754fe60SDimitry Andric CGM.getModule().getOrInsertNamedMetadata("opencl.kernels"); 2662754fe60SDimitry Andric 2672754fe60SDimitry Andric llvm::Value *Op = Fn; 2683b0f4066SDimitry Andric OpenCLMetadata->addOperand(llvm::MDNode::get(Context, Op)); 2692754fe60SDimitry Andric } 2702754fe60SDimitry Andric } 2712754fe60SDimitry Andric 272f22ef01cSRoman Divacky llvm::BasicBlock *EntryBB = createBasicBlock("entry", CurFn); 273f22ef01cSRoman Divacky 274f22ef01cSRoman Divacky // Create a marker to make it easy to insert allocas into the entryblock 275f22ef01cSRoman Divacky // later. Don't create this with the builder, because we don't want it 276f22ef01cSRoman Divacky // folded. 277ffd1746dSEd Schouten llvm::Value *Undef = llvm::UndefValue::get(Int32Ty); 278ffd1746dSEd Schouten AllocaInsertPt = new llvm::BitCastInst(Undef, Int32Ty, "", EntryBB); 279f22ef01cSRoman Divacky if (Builder.isNamePreserving()) 280f22ef01cSRoman Divacky AllocaInsertPt->setName("allocapt"); 281f22ef01cSRoman Divacky 282ffd1746dSEd Schouten ReturnBlock = getJumpDestInCurrentScope("return"); 283f22ef01cSRoman Divacky 284f22ef01cSRoman Divacky Builder.SetInsertPoint(EntryBB); 285f22ef01cSRoman Divacky 286f22ef01cSRoman Divacky // Emit subprogram debug descriptor. 287f22ef01cSRoman Divacky if (CGDebugInfo *DI = getDebugInfo()) { 2882754fe60SDimitry Andric // FIXME: what is going on here and why does it ignore all these 2892754fe60SDimitry Andric // interesting type properties? 2902754fe60SDimitry Andric QualType FnType = 2912754fe60SDimitry Andric getContext().getFunctionType(RetTy, 0, 0, 2922754fe60SDimitry Andric FunctionProtoType::ExtProtoInfo()); 2932754fe60SDimitry Andric 294f22ef01cSRoman Divacky DI->setLocation(StartLoc); 295f22ef01cSRoman Divacky DI->EmitFunctionStart(GD, FnType, CurFn, Builder); 296f22ef01cSRoman Divacky } 297f22ef01cSRoman Divacky 2982754fe60SDimitry Andric if (ShouldInstrumentFunction()) 299ffd1746dSEd Schouten EmitFunctionInstrumentation("__cyg_profile_func_enter"); 300ffd1746dSEd Schouten 3012754fe60SDimitry Andric if (CGM.getCodeGenOpts().InstrumentForProfiling) 3022754fe60SDimitry Andric EmitMCountInstrumentation(); 3032754fe60SDimitry Andric 304f22ef01cSRoman Divacky if (RetTy->isVoidType()) { 305f22ef01cSRoman Divacky // Void type; nothing to return. 306f22ef01cSRoman Divacky ReturnValue = 0; 307f22ef01cSRoman Divacky } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect && 308f22ef01cSRoman Divacky hasAggregateLLVMType(CurFnInfo->getReturnType())) { 309f22ef01cSRoman Divacky // Indirect aggregate return; emit returned value directly into sret slot. 310f22ef01cSRoman Divacky // This reduces code size, and affects correctness in C++. 311f22ef01cSRoman Divacky ReturnValue = CurFn->arg_begin(); 312f22ef01cSRoman Divacky } else { 313f22ef01cSRoman Divacky ReturnValue = CreateIRTemp(RetTy, "retval"); 314f22ef01cSRoman Divacky } 315f22ef01cSRoman Divacky 316f22ef01cSRoman Divacky EmitStartEHSpec(CurCodeDecl); 317f22ef01cSRoman Divacky EmitFunctionProlog(*CurFnInfo, CurFn, Args); 318f22ef01cSRoman Divacky 319e580952dSDimitry Andric if (D && isa<CXXMethodDecl>(D) && cast<CXXMethodDecl>(D)->isInstance()) 320e580952dSDimitry Andric CGM.getCXXABI().EmitInstanceFunctionProlog(*this); 321f22ef01cSRoman Divacky 322f22ef01cSRoman Divacky // If any of the arguments have a variably modified type, make sure to 323f22ef01cSRoman Divacky // emit the type size. 324f22ef01cSRoman Divacky for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); 325f22ef01cSRoman Divacky i != e; ++i) { 3263b0f4066SDimitry Andric QualType Ty = (*i)->getType(); 327f22ef01cSRoman Divacky 328f22ef01cSRoman Divacky if (Ty->isVariablyModifiedType()) 329f22ef01cSRoman Divacky EmitVLASize(Ty); 330f22ef01cSRoman Divacky } 331f22ef01cSRoman Divacky } 332f22ef01cSRoman Divacky 333f22ef01cSRoman Divacky void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args) { 334f22ef01cSRoman Divacky const FunctionDecl *FD = cast<FunctionDecl>(CurGD.getDecl()); 335f22ef01cSRoman Divacky assert(FD->getBody()); 336f22ef01cSRoman Divacky EmitStmt(FD->getBody()); 337f22ef01cSRoman Divacky } 338f22ef01cSRoman Divacky 339e580952dSDimitry Andric /// Tries to mark the given function nounwind based on the 340e580952dSDimitry Andric /// non-existence of any throwing calls within it. We believe this is 341e580952dSDimitry Andric /// lightweight enough to do at -O0. 342e580952dSDimitry Andric static void TryMarkNoThrow(llvm::Function *F) { 343e580952dSDimitry Andric // LLVM treats 'nounwind' on a function as part of the type, so we 344e580952dSDimitry Andric // can't do this on functions that can be overwritten. 345e580952dSDimitry Andric if (F->mayBeOverridden()) return; 346e580952dSDimitry Andric 347e580952dSDimitry Andric for (llvm::Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI) 348e580952dSDimitry Andric for (llvm::BasicBlock::iterator 349e580952dSDimitry Andric BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) 350e580952dSDimitry Andric if (llvm::CallInst *Call = dyn_cast<llvm::CallInst>(&*BI)) 351e580952dSDimitry Andric if (!Call->doesNotThrow()) 352e580952dSDimitry Andric return; 353e580952dSDimitry Andric F->setDoesNotThrow(true); 354e580952dSDimitry Andric } 355e580952dSDimitry Andric 3563b0f4066SDimitry Andric void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, 3573b0f4066SDimitry Andric const CGFunctionInfo &FnInfo) { 358f22ef01cSRoman Divacky const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); 359f22ef01cSRoman Divacky 360f22ef01cSRoman Divacky // Check if we should generate debug info for this function. 3613b0f4066SDimitry Andric if (CGM.getModuleDebugInfo() && !FD->hasAttr<NoDebugAttr>()) 3623b0f4066SDimitry Andric DebugInfo = CGM.getModuleDebugInfo(); 363f22ef01cSRoman Divacky 364f22ef01cSRoman Divacky FunctionArgList Args; 365e580952dSDimitry Andric QualType ResTy = FD->getResultType(); 366f22ef01cSRoman Divacky 367f22ef01cSRoman Divacky CurGD = GD; 368e580952dSDimitry Andric if (isa<CXXMethodDecl>(FD) && cast<CXXMethodDecl>(FD)->isInstance()) 369e580952dSDimitry Andric CGM.getCXXABI().BuildInstanceFunctionParams(*this, ResTy, Args); 370f22ef01cSRoman Divacky 3713b0f4066SDimitry Andric if (FD->getNumParams()) 372f22ef01cSRoman Divacky for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) 3733b0f4066SDimitry Andric Args.push_back(FD->getParamDecl(i)); 374f22ef01cSRoman Divacky 375f22ef01cSRoman Divacky SourceRange BodyRange; 376f22ef01cSRoman Divacky if (Stmt *Body = FD->getBody()) BodyRange = Body->getSourceRange(); 377f22ef01cSRoman Divacky 378f22ef01cSRoman Divacky // Emit the standard function prologue. 3793b0f4066SDimitry Andric StartFunction(GD, ResTy, Fn, FnInfo, Args, BodyRange.getBegin()); 380f22ef01cSRoman Divacky 381f22ef01cSRoman Divacky // Generate the body of the function. 382f22ef01cSRoman Divacky if (isa<CXXDestructorDecl>(FD)) 383f22ef01cSRoman Divacky EmitDestructorBody(Args); 384f22ef01cSRoman Divacky else if (isa<CXXConstructorDecl>(FD)) 385f22ef01cSRoman Divacky EmitConstructorBody(Args); 386f22ef01cSRoman Divacky else 387f22ef01cSRoman Divacky EmitFunctionBody(Args); 388f22ef01cSRoman Divacky 389f22ef01cSRoman Divacky // Emit the standard function epilogue. 390f22ef01cSRoman Divacky FinishFunction(BodyRange.getEnd()); 391f22ef01cSRoman Divacky 392e580952dSDimitry Andric // If we haven't marked the function nothrow through other means, do 393e580952dSDimitry Andric // a quick pass now to see if we can. 394e580952dSDimitry Andric if (!CurFn->doesNotThrow()) 395e580952dSDimitry Andric TryMarkNoThrow(CurFn); 396f22ef01cSRoman Divacky } 397f22ef01cSRoman Divacky 398f22ef01cSRoman Divacky /// ContainsLabel - Return true if the statement contains a label in it. If 399f22ef01cSRoman Divacky /// this statement is not executed normally, it not containing a label means 400f22ef01cSRoman Divacky /// that we can just remove the code. 401f22ef01cSRoman Divacky bool CodeGenFunction::ContainsLabel(const Stmt *S, bool IgnoreCaseStmts) { 402f22ef01cSRoman Divacky // Null statement, not a label! 403f22ef01cSRoman Divacky if (S == 0) return false; 404f22ef01cSRoman Divacky 405f22ef01cSRoman Divacky // If this is a label, we have to emit the code, consider something like: 406f22ef01cSRoman Divacky // if (0) { ... foo: bar(); } goto foo; 4073b0f4066SDimitry Andric // 4083b0f4066SDimitry Andric // TODO: If anyone cared, we could track __label__'s, since we know that you 4093b0f4066SDimitry Andric // can't jump to one from outside their declared region. 410f22ef01cSRoman Divacky if (isa<LabelStmt>(S)) 411f22ef01cSRoman Divacky return true; 412f22ef01cSRoman Divacky 413f22ef01cSRoman Divacky // If this is a case/default statement, and we haven't seen a switch, we have 414f22ef01cSRoman Divacky // to emit the code. 415f22ef01cSRoman Divacky if (isa<SwitchCase>(S) && !IgnoreCaseStmts) 416f22ef01cSRoman Divacky return true; 417f22ef01cSRoman Divacky 418f22ef01cSRoman Divacky // If this is a switch statement, we want to ignore cases below it. 419f22ef01cSRoman Divacky if (isa<SwitchStmt>(S)) 420f22ef01cSRoman Divacky IgnoreCaseStmts = true; 421f22ef01cSRoman Divacky 422f22ef01cSRoman Divacky // Scan subexpressions for verboten labels. 4232754fe60SDimitry Andric for (Stmt::const_child_range I = S->children(); I; ++I) 424f22ef01cSRoman Divacky if (ContainsLabel(*I, IgnoreCaseStmts)) 425f22ef01cSRoman Divacky return true; 426f22ef01cSRoman Divacky 427f22ef01cSRoman Divacky return false; 428f22ef01cSRoman Divacky } 429f22ef01cSRoman Divacky 4303b0f4066SDimitry Andric /// containsBreak - Return true if the statement contains a break out of it. 4313b0f4066SDimitry Andric /// If the statement (recursively) contains a switch or loop with a break 4323b0f4066SDimitry Andric /// inside of it, this is fine. 4333b0f4066SDimitry Andric bool CodeGenFunction::containsBreak(const Stmt *S) { 4343b0f4066SDimitry Andric // Null statement, not a label! 4353b0f4066SDimitry Andric if (S == 0) return false; 436f22ef01cSRoman Divacky 4373b0f4066SDimitry Andric // If this is a switch or loop that defines its own break scope, then we can 4383b0f4066SDimitry Andric // include it and anything inside of it. 4393b0f4066SDimitry Andric if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || isa<DoStmt>(S) || 4403b0f4066SDimitry Andric isa<ForStmt>(S)) 4413b0f4066SDimitry Andric return false; 4423b0f4066SDimitry Andric 4433b0f4066SDimitry Andric if (isa<BreakStmt>(S)) 4443b0f4066SDimitry Andric return true; 4453b0f4066SDimitry Andric 4463b0f4066SDimitry Andric // Scan subexpressions for verboten breaks. 4473b0f4066SDimitry Andric for (Stmt::const_child_range I = S->children(); I; ++I) 4483b0f4066SDimitry Andric if (containsBreak(*I)) 4493b0f4066SDimitry Andric return true; 4503b0f4066SDimitry Andric 4513b0f4066SDimitry Andric return false; 4523b0f4066SDimitry Andric } 4533b0f4066SDimitry Andric 4543b0f4066SDimitry Andric 4553b0f4066SDimitry Andric /// ConstantFoldsToSimpleInteger - If the specified expression does not fold 4563b0f4066SDimitry Andric /// to a constant, or if it does but contains a label, return false. If it 4573b0f4066SDimitry Andric /// constant folds return true and set the boolean result in Result. 4583b0f4066SDimitry Andric bool CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond, 4593b0f4066SDimitry Andric bool &ResultBool) { 4603b0f4066SDimitry Andric llvm::APInt ResultInt; 4613b0f4066SDimitry Andric if (!ConstantFoldsToSimpleInteger(Cond, ResultInt)) 4623b0f4066SDimitry Andric return false; 4633b0f4066SDimitry Andric 4643b0f4066SDimitry Andric ResultBool = ResultInt.getBoolValue(); 4653b0f4066SDimitry Andric return true; 4663b0f4066SDimitry Andric } 4673b0f4066SDimitry Andric 4683b0f4066SDimitry Andric /// ConstantFoldsToSimpleInteger - If the specified expression does not fold 4693b0f4066SDimitry Andric /// to a constant, or if it does but contains a label, return false. If it 4703b0f4066SDimitry Andric /// constant folds return true and set the folded value. 4713b0f4066SDimitry Andric bool CodeGenFunction:: 4723b0f4066SDimitry Andric ConstantFoldsToSimpleInteger(const Expr *Cond, llvm::APInt &ResultInt) { 473f22ef01cSRoman Divacky // FIXME: Rename and handle conversion of other evaluatable things 474f22ef01cSRoman Divacky // to bool. 475f22ef01cSRoman Divacky Expr::EvalResult Result; 476f22ef01cSRoman Divacky if (!Cond->Evaluate(Result, getContext()) || !Result.Val.isInt() || 477f22ef01cSRoman Divacky Result.HasSideEffects) 4783b0f4066SDimitry Andric return false; // Not foldable, not integer or not fully evaluatable. 479f22ef01cSRoman Divacky 480f22ef01cSRoman Divacky if (CodeGenFunction::ContainsLabel(Cond)) 4813b0f4066SDimitry Andric return false; // Contains a label. 482f22ef01cSRoman Divacky 4833b0f4066SDimitry Andric ResultInt = Result.Val.getInt(); 4843b0f4066SDimitry Andric return true; 485f22ef01cSRoman Divacky } 486f22ef01cSRoman Divacky 487f22ef01cSRoman Divacky 4883b0f4066SDimitry Andric 489f22ef01cSRoman Divacky /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an if 490f22ef01cSRoman Divacky /// statement) to the specified blocks. Based on the condition, this might try 491f22ef01cSRoman Divacky /// to simplify the codegen of the conditional based on the branch. 492f22ef01cSRoman Divacky /// 493f22ef01cSRoman Divacky void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, 494f22ef01cSRoman Divacky llvm::BasicBlock *TrueBlock, 495f22ef01cSRoman Divacky llvm::BasicBlock *FalseBlock) { 4963b0f4066SDimitry Andric Cond = Cond->IgnoreParens(); 497f22ef01cSRoman Divacky 498f22ef01cSRoman Divacky if (const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) { 499f22ef01cSRoman Divacky // Handle X && Y in a condition. 500e580952dSDimitry Andric if (CondBOp->getOpcode() == BO_LAnd) { 501f22ef01cSRoman Divacky // If we have "1 && X", simplify the code. "0 && X" would have constant 502f22ef01cSRoman Divacky // folded if the case was simple enough. 5033b0f4066SDimitry Andric bool ConstantBool = false; 5043b0f4066SDimitry Andric if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), ConstantBool) && 5053b0f4066SDimitry Andric ConstantBool) { 506f22ef01cSRoman Divacky // br(1 && X) -> br(X). 507f22ef01cSRoman Divacky return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock); 508f22ef01cSRoman Divacky } 509f22ef01cSRoman Divacky 510f22ef01cSRoman Divacky // If we have "X && 1", simplify the code to use an uncond branch. 511f22ef01cSRoman Divacky // "X && 0" would have been constant folded to 0. 5123b0f4066SDimitry Andric if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), ConstantBool) && 5133b0f4066SDimitry Andric ConstantBool) { 514f22ef01cSRoman Divacky // br(X && 1) -> br(X). 515f22ef01cSRoman Divacky return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock); 516f22ef01cSRoman Divacky } 517f22ef01cSRoman Divacky 518f22ef01cSRoman Divacky // Emit the LHS as a conditional. If the LHS conditional is false, we 519f22ef01cSRoman Divacky // want to jump to the FalseBlock. 520f22ef01cSRoman Divacky llvm::BasicBlock *LHSTrue = createBasicBlock("land.lhs.true"); 5212754fe60SDimitry Andric 5222754fe60SDimitry Andric ConditionalEvaluation eval(*this); 523f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock); 524f22ef01cSRoman Divacky EmitBlock(LHSTrue); 525f22ef01cSRoman Divacky 526f22ef01cSRoman Divacky // Any temporaries created here are conditional. 5272754fe60SDimitry Andric eval.begin(*this); 528f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock); 5292754fe60SDimitry Andric eval.end(*this); 530f22ef01cSRoman Divacky 531f22ef01cSRoman Divacky return; 5323b0f4066SDimitry Andric } 5333b0f4066SDimitry Andric 5343b0f4066SDimitry Andric if (CondBOp->getOpcode() == BO_LOr) { 535f22ef01cSRoman Divacky // If we have "0 || X", simplify the code. "1 || X" would have constant 536f22ef01cSRoman Divacky // folded if the case was simple enough. 5373b0f4066SDimitry Andric bool ConstantBool = false; 5383b0f4066SDimitry Andric if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), ConstantBool) && 5393b0f4066SDimitry Andric !ConstantBool) { 540f22ef01cSRoman Divacky // br(0 || X) -> br(X). 541f22ef01cSRoman Divacky return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock); 542f22ef01cSRoman Divacky } 543f22ef01cSRoman Divacky 544f22ef01cSRoman Divacky // If we have "X || 0", simplify the code to use an uncond branch. 545f22ef01cSRoman Divacky // "X || 1" would have been constant folded to 1. 5463b0f4066SDimitry Andric if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), ConstantBool) && 5473b0f4066SDimitry Andric !ConstantBool) { 548f22ef01cSRoman Divacky // br(X || 0) -> br(X). 549f22ef01cSRoman Divacky return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock); 550f22ef01cSRoman Divacky } 551f22ef01cSRoman Divacky 552f22ef01cSRoman Divacky // Emit the LHS as a conditional. If the LHS conditional is true, we 553f22ef01cSRoman Divacky // want to jump to the TrueBlock. 554f22ef01cSRoman Divacky llvm::BasicBlock *LHSFalse = createBasicBlock("lor.lhs.false"); 5552754fe60SDimitry Andric 5562754fe60SDimitry Andric ConditionalEvaluation eval(*this); 557f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse); 558f22ef01cSRoman Divacky EmitBlock(LHSFalse); 559f22ef01cSRoman Divacky 560f22ef01cSRoman Divacky // Any temporaries created here are conditional. 5612754fe60SDimitry Andric eval.begin(*this); 562f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock); 5632754fe60SDimitry Andric eval.end(*this); 564f22ef01cSRoman Divacky 565f22ef01cSRoman Divacky return; 566f22ef01cSRoman Divacky } 567f22ef01cSRoman Divacky } 568f22ef01cSRoman Divacky 569f22ef01cSRoman Divacky if (const UnaryOperator *CondUOp = dyn_cast<UnaryOperator>(Cond)) { 570f22ef01cSRoman Divacky // br(!x, t, f) -> br(x, f, t) 571e580952dSDimitry Andric if (CondUOp->getOpcode() == UO_LNot) 572f22ef01cSRoman Divacky return EmitBranchOnBoolExpr(CondUOp->getSubExpr(), FalseBlock, TrueBlock); 573f22ef01cSRoman Divacky } 574f22ef01cSRoman Divacky 575f22ef01cSRoman Divacky if (const ConditionalOperator *CondOp = dyn_cast<ConditionalOperator>(Cond)) { 576f22ef01cSRoman Divacky // Handle ?: operator. 577f22ef01cSRoman Divacky 578f22ef01cSRoman Divacky // Just ignore GNU ?: extension. 579f22ef01cSRoman Divacky if (CondOp->getLHS()) { 580f22ef01cSRoman Divacky // br(c ? x : y, t, f) -> br(c, br(x, t, f), br(y, t, f)) 581f22ef01cSRoman Divacky llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true"); 582f22ef01cSRoman Divacky llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false"); 5832754fe60SDimitry Andric 5842754fe60SDimitry Andric ConditionalEvaluation cond(*this); 585f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondOp->getCond(), LHSBlock, RHSBlock); 5862754fe60SDimitry Andric 5872754fe60SDimitry Andric cond.begin(*this); 588f22ef01cSRoman Divacky EmitBlock(LHSBlock); 589f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondOp->getLHS(), TrueBlock, FalseBlock); 5902754fe60SDimitry Andric cond.end(*this); 5912754fe60SDimitry Andric 5922754fe60SDimitry Andric cond.begin(*this); 593f22ef01cSRoman Divacky EmitBlock(RHSBlock); 594f22ef01cSRoman Divacky EmitBranchOnBoolExpr(CondOp->getRHS(), TrueBlock, FalseBlock); 5952754fe60SDimitry Andric cond.end(*this); 5962754fe60SDimitry Andric 597f22ef01cSRoman Divacky return; 598f22ef01cSRoman Divacky } 599f22ef01cSRoman Divacky } 600f22ef01cSRoman Divacky 601f22ef01cSRoman Divacky // Emit the code with the fully general case. 602f22ef01cSRoman Divacky llvm::Value *CondV = EvaluateExprAsBool(Cond); 603f22ef01cSRoman Divacky Builder.CreateCondBr(CondV, TrueBlock, FalseBlock); 604f22ef01cSRoman Divacky } 605f22ef01cSRoman Divacky 606f22ef01cSRoman Divacky /// ErrorUnsupported - Print out an error that codegen doesn't support the 607f22ef01cSRoman Divacky /// specified stmt yet. 608f22ef01cSRoman Divacky void CodeGenFunction::ErrorUnsupported(const Stmt *S, const char *Type, 609f22ef01cSRoman Divacky bool OmitOnError) { 610f22ef01cSRoman Divacky CGM.ErrorUnsupported(S, Type, OmitOnError); 611f22ef01cSRoman Divacky } 612f22ef01cSRoman Divacky 6132754fe60SDimitry Andric /// emitNonZeroVLAInit - Emit the "zero" initialization of a 6142754fe60SDimitry Andric /// variable-length array whose elements have a non-zero bit-pattern. 6152754fe60SDimitry Andric /// 6162754fe60SDimitry Andric /// \param src - a char* pointing to the bit-pattern for a single 6172754fe60SDimitry Andric /// base element of the array 6182754fe60SDimitry Andric /// \param sizeInChars - the total size of the VLA, in chars 6192754fe60SDimitry Andric /// \param align - the total alignment of the VLA 6202754fe60SDimitry Andric static void emitNonZeroVLAInit(CodeGenFunction &CGF, QualType baseType, 6212754fe60SDimitry Andric llvm::Value *dest, llvm::Value *src, 6222754fe60SDimitry Andric llvm::Value *sizeInChars) { 6232754fe60SDimitry Andric std::pair<CharUnits,CharUnits> baseSizeAndAlign 6242754fe60SDimitry Andric = CGF.getContext().getTypeInfoInChars(baseType); 6252754fe60SDimitry Andric 6262754fe60SDimitry Andric CGBuilderTy &Builder = CGF.Builder; 6272754fe60SDimitry Andric 6282754fe60SDimitry Andric llvm::Value *baseSizeInChars 6292754fe60SDimitry Andric = llvm::ConstantInt::get(CGF.IntPtrTy, baseSizeAndAlign.first.getQuantity()); 6302754fe60SDimitry Andric 6312754fe60SDimitry Andric const llvm::Type *i8p = Builder.getInt8PtrTy(); 6322754fe60SDimitry Andric 6332754fe60SDimitry Andric llvm::Value *begin = Builder.CreateBitCast(dest, i8p, "vla.begin"); 6342754fe60SDimitry Andric llvm::Value *end = Builder.CreateInBoundsGEP(dest, sizeInChars, "vla.end"); 6352754fe60SDimitry Andric 6362754fe60SDimitry Andric llvm::BasicBlock *originBB = CGF.Builder.GetInsertBlock(); 6372754fe60SDimitry Andric llvm::BasicBlock *loopBB = CGF.createBasicBlock("vla-init.loop"); 6382754fe60SDimitry Andric llvm::BasicBlock *contBB = CGF.createBasicBlock("vla-init.cont"); 6392754fe60SDimitry Andric 6402754fe60SDimitry Andric // Make a loop over the VLA. C99 guarantees that the VLA element 6412754fe60SDimitry Andric // count must be nonzero. 6422754fe60SDimitry Andric CGF.EmitBlock(loopBB); 6432754fe60SDimitry Andric 6443b0f4066SDimitry Andric llvm::PHINode *cur = Builder.CreatePHI(i8p, 2, "vla.cur"); 6452754fe60SDimitry Andric cur->addIncoming(begin, originBB); 6462754fe60SDimitry Andric 6472754fe60SDimitry Andric // memcpy the individual element bit-pattern. 6482754fe60SDimitry Andric Builder.CreateMemCpy(cur, src, baseSizeInChars, 6492754fe60SDimitry Andric baseSizeAndAlign.second.getQuantity(), 6502754fe60SDimitry Andric /*volatile*/ false); 6512754fe60SDimitry Andric 6522754fe60SDimitry Andric // Go to the next element. 6532754fe60SDimitry Andric llvm::Value *next = Builder.CreateConstInBoundsGEP1_32(cur, 1, "vla.next"); 6542754fe60SDimitry Andric 6552754fe60SDimitry Andric // Leave if that's the end of the VLA. 6562754fe60SDimitry Andric llvm::Value *done = Builder.CreateICmpEQ(next, end, "vla-init.isdone"); 6572754fe60SDimitry Andric Builder.CreateCondBr(done, contBB, loopBB); 6582754fe60SDimitry Andric cur->addIncoming(next, loopBB); 6592754fe60SDimitry Andric 6602754fe60SDimitry Andric CGF.EmitBlock(contBB); 6612754fe60SDimitry Andric } 6622754fe60SDimitry Andric 663f22ef01cSRoman Divacky void 664f22ef01cSRoman Divacky CodeGenFunction::EmitNullInitialization(llvm::Value *DestPtr, QualType Ty) { 665f22ef01cSRoman Divacky // Ignore empty classes in C++. 666f22ef01cSRoman Divacky if (getContext().getLangOptions().CPlusPlus) { 667f22ef01cSRoman Divacky if (const RecordType *RT = Ty->getAs<RecordType>()) { 668f22ef01cSRoman Divacky if (cast<CXXRecordDecl>(RT->getDecl())->isEmpty()) 669f22ef01cSRoman Divacky return; 670f22ef01cSRoman Divacky } 671f22ef01cSRoman Divacky } 672f22ef01cSRoman Divacky 673e580952dSDimitry Andric // Cast the dest ptr to the appropriate i8 pointer type. 674e580952dSDimitry Andric unsigned DestAS = 675e580952dSDimitry Andric cast<llvm::PointerType>(DestPtr->getType())->getAddressSpace(); 6762754fe60SDimitry Andric const llvm::Type *BP = Builder.getInt8PtrTy(DestAS); 677f22ef01cSRoman Divacky if (DestPtr->getType() != BP) 678f22ef01cSRoman Divacky DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp"); 679f22ef01cSRoman Divacky 680f22ef01cSRoman Divacky // Get size and alignment info for this aggregate. 6813b0f4066SDimitry Andric std::pair<CharUnits, CharUnits> TypeInfo = 6823b0f4066SDimitry Andric getContext().getTypeInfoInChars(Ty); 6833b0f4066SDimitry Andric CharUnits Size = TypeInfo.first; 6843b0f4066SDimitry Andric CharUnits Align = TypeInfo.second; 6852754fe60SDimitry Andric 6862754fe60SDimitry Andric llvm::Value *SizeVal; 6872754fe60SDimitry Andric const VariableArrayType *vla; 688f22ef01cSRoman Divacky 689f22ef01cSRoman Divacky // Don't bother emitting a zero-byte memset. 6903b0f4066SDimitry Andric if (Size.isZero()) { 6912754fe60SDimitry Andric // But note that getTypeInfo returns 0 for a VLA. 6922754fe60SDimitry Andric if (const VariableArrayType *vlaType = 6932754fe60SDimitry Andric dyn_cast_or_null<VariableArrayType>( 6942754fe60SDimitry Andric getContext().getAsArrayType(Ty))) { 6952754fe60SDimitry Andric SizeVal = GetVLASize(vlaType); 6962754fe60SDimitry Andric vla = vlaType; 6972754fe60SDimitry Andric } else { 698f22ef01cSRoman Divacky return; 6992754fe60SDimitry Andric } 7002754fe60SDimitry Andric } else { 7013b0f4066SDimitry Andric SizeVal = llvm::ConstantInt::get(IntPtrTy, Size.getQuantity()); 7022754fe60SDimitry Andric vla = 0; 7032754fe60SDimitry Andric } 704e580952dSDimitry Andric 705e580952dSDimitry Andric // If the type contains a pointer to data member we can't memset it to zero. 706e580952dSDimitry Andric // Instead, create a null constant and copy it to the destination. 7072754fe60SDimitry Andric // TODO: there are other patterns besides zero that we can usefully memset, 7082754fe60SDimitry Andric // like -1, which happens to be the pattern used by member-pointers. 709e580952dSDimitry Andric if (!CGM.getTypes().isZeroInitializable(Ty)) { 7102754fe60SDimitry Andric // For a VLA, emit a single element, then splat that over the VLA. 7112754fe60SDimitry Andric if (vla) Ty = getContext().getBaseElementType(vla); 7122754fe60SDimitry Andric 713e580952dSDimitry Andric llvm::Constant *NullConstant = CGM.EmitNullConstant(Ty); 714e580952dSDimitry Andric 715e580952dSDimitry Andric llvm::GlobalVariable *NullVariable = 716e580952dSDimitry Andric new llvm::GlobalVariable(CGM.getModule(), NullConstant->getType(), 717e580952dSDimitry Andric /*isConstant=*/true, 718e580952dSDimitry Andric llvm::GlobalVariable::PrivateLinkage, 719e580952dSDimitry Andric NullConstant, llvm::Twine()); 720e580952dSDimitry Andric llvm::Value *SrcPtr = 721e580952dSDimitry Andric Builder.CreateBitCast(NullVariable, Builder.getInt8PtrTy()); 722e580952dSDimitry Andric 7232754fe60SDimitry Andric if (vla) return emitNonZeroVLAInit(*this, Ty, DestPtr, SrcPtr, SizeVal); 724e580952dSDimitry Andric 725e580952dSDimitry Andric // Get and call the appropriate llvm.memcpy overload. 7263b0f4066SDimitry Andric Builder.CreateMemCpy(DestPtr, SrcPtr, SizeVal, Align.getQuantity(), false); 727e580952dSDimitry Andric return; 728e580952dSDimitry Andric } 729e580952dSDimitry Andric 730e580952dSDimitry Andric // Otherwise, just memset the whole thing to zero. This is legal 731e580952dSDimitry Andric // because in LLVM, all default initializers (other than the ones we just 732e580952dSDimitry Andric // handled above) are guaranteed to have a bit pattern of all zeros. 7333b0f4066SDimitry Andric Builder.CreateMemSet(DestPtr, Builder.getInt8(0), SizeVal, 7343b0f4066SDimitry Andric Align.getQuantity(), false); 735f22ef01cSRoman Divacky } 736f22ef01cSRoman Divacky 7372754fe60SDimitry Andric llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelDecl *L) { 738f22ef01cSRoman Divacky // Make sure that there is a block for the indirect goto. 739f22ef01cSRoman Divacky if (IndirectBranch == 0) 740f22ef01cSRoman Divacky GetIndirectGotoBlock(); 741f22ef01cSRoman Divacky 742e580952dSDimitry Andric llvm::BasicBlock *BB = getJumpDestForLabel(L).getBlock(); 743f22ef01cSRoman Divacky 744f22ef01cSRoman Divacky // Make sure the indirect branch includes all of the address-taken blocks. 745f22ef01cSRoman Divacky IndirectBranch->addDestination(BB); 746f22ef01cSRoman Divacky return llvm::BlockAddress::get(CurFn, BB); 747f22ef01cSRoman Divacky } 748f22ef01cSRoman Divacky 749f22ef01cSRoman Divacky llvm::BasicBlock *CodeGenFunction::GetIndirectGotoBlock() { 750f22ef01cSRoman Divacky // If we already made the indirect branch for indirect goto, return its block. 751f22ef01cSRoman Divacky if (IndirectBranch) return IndirectBranch->getParent(); 752f22ef01cSRoman Divacky 753f22ef01cSRoman Divacky CGBuilderTy TmpBuilder(createBasicBlock("indirectgoto")); 754f22ef01cSRoman Divacky 755f22ef01cSRoman Divacky // Create the PHI node that indirect gotos will add entries to. 7563b0f4066SDimitry Andric llvm::Value *DestVal = TmpBuilder.CreatePHI(Int8PtrTy, 0, 7573b0f4066SDimitry Andric "indirect.goto.dest"); 758f22ef01cSRoman Divacky 759f22ef01cSRoman Divacky // Create the indirect branch instruction. 760f22ef01cSRoman Divacky IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal); 761f22ef01cSRoman Divacky return IndirectBranch->getParent(); 762f22ef01cSRoman Divacky } 763f22ef01cSRoman Divacky 764f22ef01cSRoman Divacky llvm::Value *CodeGenFunction::GetVLASize(const VariableArrayType *VAT) { 765f22ef01cSRoman Divacky llvm::Value *&SizeEntry = VLASizeMap[VAT->getSizeExpr()]; 766f22ef01cSRoman Divacky 767f22ef01cSRoman Divacky assert(SizeEntry && "Did not emit size for type"); 768f22ef01cSRoman Divacky return SizeEntry; 769f22ef01cSRoman Divacky } 770f22ef01cSRoman Divacky 771f22ef01cSRoman Divacky llvm::Value *CodeGenFunction::EmitVLASize(QualType Ty) { 772f22ef01cSRoman Divacky assert(Ty->isVariablyModifiedType() && 773f22ef01cSRoman Divacky "Must pass variably modified type to EmitVLASizes!"); 774f22ef01cSRoman Divacky 775f22ef01cSRoman Divacky EnsureInsertPoint(); 776f22ef01cSRoman Divacky 777f22ef01cSRoman Divacky if (const VariableArrayType *VAT = getContext().getAsVariableArrayType(Ty)) { 7782754fe60SDimitry Andric // unknown size indication requires no size computation. 7792754fe60SDimitry Andric if (!VAT->getSizeExpr()) 7802754fe60SDimitry Andric return 0; 781f22ef01cSRoman Divacky llvm::Value *&SizeEntry = VLASizeMap[VAT->getSizeExpr()]; 782f22ef01cSRoman Divacky 783f22ef01cSRoman Divacky if (!SizeEntry) { 784f22ef01cSRoman Divacky const llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); 785f22ef01cSRoman Divacky 786f22ef01cSRoman Divacky // Get the element size; 787f22ef01cSRoman Divacky QualType ElemTy = VAT->getElementType(); 788f22ef01cSRoman Divacky llvm::Value *ElemSize; 789f22ef01cSRoman Divacky if (ElemTy->isVariableArrayType()) 790f22ef01cSRoman Divacky ElemSize = EmitVLASize(ElemTy); 791f22ef01cSRoman Divacky else 792f22ef01cSRoman Divacky ElemSize = llvm::ConstantInt::get(SizeTy, 793f22ef01cSRoman Divacky getContext().getTypeSizeInChars(ElemTy).getQuantity()); 794f22ef01cSRoman Divacky 795f22ef01cSRoman Divacky llvm::Value *NumElements = EmitScalarExpr(VAT->getSizeExpr()); 796f22ef01cSRoman Divacky NumElements = Builder.CreateIntCast(NumElements, SizeTy, false, "tmp"); 797f22ef01cSRoman Divacky 798f22ef01cSRoman Divacky SizeEntry = Builder.CreateMul(ElemSize, NumElements); 799f22ef01cSRoman Divacky } 800f22ef01cSRoman Divacky 801f22ef01cSRoman Divacky return SizeEntry; 802f22ef01cSRoman Divacky } 803f22ef01cSRoman Divacky 804f22ef01cSRoman Divacky if (const ArrayType *AT = dyn_cast<ArrayType>(Ty)) { 805f22ef01cSRoman Divacky EmitVLASize(AT->getElementType()); 806f22ef01cSRoman Divacky return 0; 807f22ef01cSRoman Divacky } 808f22ef01cSRoman Divacky 8092754fe60SDimitry Andric if (const ParenType *PT = dyn_cast<ParenType>(Ty)) { 8102754fe60SDimitry Andric EmitVLASize(PT->getInnerType()); 8112754fe60SDimitry Andric return 0; 8122754fe60SDimitry Andric } 8132754fe60SDimitry Andric 814f22ef01cSRoman Divacky const PointerType *PT = Ty->getAs<PointerType>(); 815f22ef01cSRoman Divacky assert(PT && "unknown VM type!"); 816f22ef01cSRoman Divacky EmitVLASize(PT->getPointeeType()); 817f22ef01cSRoman Divacky return 0; 818f22ef01cSRoman Divacky } 819f22ef01cSRoman Divacky 820f22ef01cSRoman Divacky llvm::Value* CodeGenFunction::EmitVAListRef(const Expr* E) { 8212754fe60SDimitry Andric if (getContext().getBuiltinVaListType()->isArrayType()) 822f22ef01cSRoman Divacky return EmitScalarExpr(E); 823f22ef01cSRoman Divacky return EmitLValue(E).getAddress(); 824f22ef01cSRoman Divacky } 825f22ef01cSRoman Divacky 826e580952dSDimitry Andric void CodeGenFunction::EmitDeclRefExprDbgValue(const DeclRefExpr *E, 8272754fe60SDimitry Andric llvm::Constant *Init) { 828e580952dSDimitry Andric assert (Init && "Invalid DeclRefExpr initializer!"); 829e580952dSDimitry Andric if (CGDebugInfo *Dbg = getDebugInfo()) 8302754fe60SDimitry Andric Dbg->EmitGlobalVariable(E->getDecl(), Init); 8312754fe60SDimitry Andric } 8322754fe60SDimitry Andric 8332754fe60SDimitry Andric CodeGenFunction::PeepholeProtection 8342754fe60SDimitry Andric CodeGenFunction::protectFromPeepholes(RValue rvalue) { 8352754fe60SDimitry Andric // At the moment, the only aggressive peephole we do in IR gen 8362754fe60SDimitry Andric // is trunc(zext) folding, but if we add more, we can easily 8372754fe60SDimitry Andric // extend this protection. 8382754fe60SDimitry Andric 8392754fe60SDimitry Andric if (!rvalue.isScalar()) return PeepholeProtection(); 8402754fe60SDimitry Andric llvm::Value *value = rvalue.getScalarVal(); 8412754fe60SDimitry Andric if (!isa<llvm::ZExtInst>(value)) return PeepholeProtection(); 8422754fe60SDimitry Andric 8432754fe60SDimitry Andric // Just make an extra bitcast. 8442754fe60SDimitry Andric assert(HaveInsertPoint()); 8452754fe60SDimitry Andric llvm::Instruction *inst = new llvm::BitCastInst(value, value->getType(), "", 8462754fe60SDimitry Andric Builder.GetInsertBlock()); 8472754fe60SDimitry Andric 8482754fe60SDimitry Andric PeepholeProtection protection; 8492754fe60SDimitry Andric protection.Inst = inst; 8502754fe60SDimitry Andric return protection; 8512754fe60SDimitry Andric } 8522754fe60SDimitry Andric 8532754fe60SDimitry Andric void CodeGenFunction::unprotectFromPeepholes(PeepholeProtection protection) { 8542754fe60SDimitry Andric if (!protection.Inst) return; 8552754fe60SDimitry Andric 8562754fe60SDimitry Andric // In theory, we could try to duplicate the peepholes now, but whatever. 8572754fe60SDimitry Andric protection.Inst->eraseFromParent(); 858e580952dSDimitry Andric } 859