: BlockFunction(cgm, *this, Builder), CGM(cgm),
Target(CGM.getContext().Target),
Builder(cgm.getModule().getContext()),
-#ifndef USEINDIRECTBRANCH
- DebugInfo(0), IndirectGotoSwitch(0),
-#else
DebugInfo(0), IndirectBranch(0),
-#endif
SwitchInsn(0), CaseRangeBlock(0), InvokeDest(0),
CXXThisDecl(0) {
LLVMIntTy = ConvertType(getContext().IntTy);
EmitFunctionEpilog(*CurFnInfo, ReturnValue);
-#ifdef USEINDIRECTBRANCH
// If someone did an indirect goto, emit the indirect goto block at the end of
// the function.
if (IndirectBranch) {
Builder.ClearInsertionPoint();
}
-
-#endif
// Remove the AllocaInsertPt instruction, which is just a convenience for us.
llvm::Instruction *Ptr = AllocaInsertPt;
AllocaInsertPt = 0;
Ptr->eraseFromParent();
-#ifdef USEINDIRECTBRANCH
// If someone took the address of a label but never did an indirect goto, we
// made a zero entry PHI node, which is illegal, zap it now.
PN->eraseFromParent();
}
}
-
-#endif
}
void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
TypeInfo.second/8));
}
-#ifndef USEINDIRECTBRANCH
-unsigned CodeGenFunction::GetIDForAddrOfLabel(const LabelStmt *L) {
- // Use LabelIDs.size()+1 as the new ID if one hasn't been assigned.
- unsigned &Entry = LabelIDs[L];
- if (Entry) return Entry;
-#else
-
llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelStmt *L) {
// Make sure that there is a block for the indirect goto.
if (IndirectBranch == 0)
GetIndirectGotoBlock();
-#endif
-#ifndef USEINDIRECTBRANCH
- Entry = LabelIDs.size();
-#else
llvm::BasicBlock *BB = getBasicBlockForLabel(L);
-#endif
-
-#ifndef USEINDIRECTBRANCH
- // If this is the first "address taken" of a label and the indirect goto has
- // already been seen, add this to it.
- if (IndirectGotoSwitch) {
- // If this is the first address-taken label, set it as the default dest.
- if (Entry == 1)
- IndirectGotoSwitch->setSuccessor(0, getBasicBlockForLabel(L));
- else {
- // Otherwise add it to the switch as a new dest.
- const llvm::IntegerType *Int32Ty = llvm::Type::getInt32Ty(VMContext);
- IndirectGotoSwitch->addCase(llvm::ConstantInt::get(Int32Ty, Entry),
- getBasicBlockForLabel(L));
- }
- }
- return Entry;
-#else
// Make sure the indirect branch includes all of the address-taken blocks.
IndirectBranch->addDestination(BB);
return llvm::BlockAddress::get(CurFn, BB);
-#endif
}
llvm::BasicBlock *CodeGenFunction::GetIndirectGotoBlock() {
-#ifndef USEINDIRECTBRANCH
- // If we already made the switch stmt for indirect goto, return its block.
- if (IndirectGotoSwitch) return IndirectGotoSwitch->getParent();
-#else
// If we already made the indirect branch for indirect goto, return its block.
if (IndirectBranch) return IndirectBranch->getParent();
-#endif
-#ifndef USEINDIRECTBRANCH
- EmitBlock(createBasicBlock("indirectgoto"));
-#else
CGBuilderTy TmpBuilder(createBasicBlock("indirectgoto"));
-#endif
-#ifndef USEINDIRECTBRANCH
- const llvm::IntegerType *Int32Ty = llvm::Type::getInt32Ty(VMContext);
-#else
const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
-#endif
// Create the PHI node that indirect gotos will add entries to.
-#ifndef USEINDIRECTBRANCH
- llvm::Value *DestVal = Builder.CreatePHI(Int32Ty, "indirect.goto.dest");
-#else
llvm::Value *DestVal = TmpBuilder.CreatePHI(Int8PtrTy, "indirect.goto.dest");
-#endif
-
-#ifndef USEINDIRECTBRANCH
- // Create the switch instruction. For now, set the insert block to this block
- // which will be fixed as labels are added.
- IndirectGotoSwitch = Builder.CreateSwitch(DestVal, Builder.GetInsertBlock());
-
- // Clear the insertion point to indicate we are in unreachable code.
- Builder.ClearInsertionPoint();
- // If we already have labels created, add them.
- if (!LabelIDs.empty()) {
- // Invert LabelID's so that the order is determinstic.
- std::vector<const LabelStmt*> AddrTakenLabelsByID;
- AddrTakenLabelsByID.resize(LabelIDs.size());
-
- for (std::map<const LabelStmt*,unsigned>::iterator
- LI = LabelIDs.begin(), LE = LabelIDs.end(); LI != LE; ++LI) {
- assert(LI->second-1 < AddrTakenLabelsByID.size() &&
- "Numbering inconsistent");
- AddrTakenLabelsByID[LI->second-1] = LI->first;
- }
-
- // Set the default entry as the first block.
- IndirectGotoSwitch->setSuccessor(0,
- getBasicBlockForLabel(AddrTakenLabelsByID[0]));
-
- // FIXME: The iteration order of this is nondeterminstic!
- for (unsigned i = 1, e = AddrTakenLabelsByID.size(); i != e; ++i)
- IndirectGotoSwitch->addCase(llvm::ConstantInt::get(Int32Ty, i+1),
- getBasicBlockForLabel(AddrTakenLabelsByID[i]));
- } else {
- // Otherwise, create a dead block and set it as the default dest. This will
- // be removed by the optimizers after the indirect goto is set up.
- llvm::BasicBlock *Dummy = createBasicBlock("indgoto.dummy");
- EmitBlock(Dummy);
- IndirectGotoSwitch->setSuccessor(0, Dummy);
- Builder.CreateUnreachable();
- Builder.ClearInsertionPoint();
- }
-
- return IndirectGotoSwitch->getParent();
-#else
// Create the indirect branch instruction.
IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal);
return IndirectBranch->getParent();
-#endif
}
llvm::Value *CodeGenFunction::GetVLASize(const VariableArrayType *VAT) {
private:
CGDebugInfo *DebugInfo;
-#ifndef USEINDIRECTBRANCH
- /// LabelIDs - Track arbitrary ids assigned to labels for use in implementing
- /// the GCC address-of-label extension and indirect goto. IDs are assigned to
- /// labels inside getIDForAddrOfLabel().
- std::map<const LabelStmt*, unsigned> LabelIDs;
-#else
/// IndirectBranch - The first time an indirect goto is seen we create a
/// block with an indirect branch. Every time we see the address of a label
/// taken, we add the label to the indirect goto. Every subsequent indirect
/// goto is codegen'd as a jump to the IndirectBranch's basic block.
llvm::IndirectBrInst *IndirectBranch;
-#endif
-
-#ifndef USEINDIRECTBRANCH
- /// IndirectGotoSwitch - The first time an indirect goto is seen we create a
- /// block with the switch for the indirect gotos. Every time we see the
- /// address of a label taken, we add the label to the indirect goto. Every
- /// subsequent indirect goto is codegen'd as a jump to the
- /// IndirectGotoSwitch's basic block.
- llvm::SwitchInst *IndirectGotoSwitch;
-#endif
/// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
/// decls.
llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
/// the input field number being accessed.
static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant *Elts);
-#ifndef USEINDIRECTBRANCH
- unsigned GetIDForAddrOfLabel(const LabelStmt *L);
-#else
llvm::BlockAddress *GetAddrOfLabel(const LabelStmt *L);
-#endif
llvm::BasicBlock *GetIndirectGotoBlock();
/// EmitMemSetToZero - Generate code to memset a value of the given type to 0.