zcov: / lib/CodeGen/CodeGenFunction.cpp


Files: 1 Branches Taken: 75.5% 207 / 274
Generated: 2010-02-10 01:31 Branches Executed: 93.4% 256 / 274
Line Coverage: 89.3% 350 / 392


Programs: 1 Runs 2897


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

Generated: 2010-02-10 01:31 by zcov