reimplement codegen for indirect goto with the following advantages:
1. CGF now has fewer bytes of state (one pointer instead of a vector).
2. The generated code is determinstic, instead of getting labels in
'map order' based on pointer addresses.
3. Clang now emits one 'indirect goto switch' for each function, instead
of one for each indirect goto. This fixes an M*N = N^2 IR size issue
when there are lots of address-taken labels and lots of indirect gotos.
4. This also makes the default cause do something useful, reducing the
size of the jump table needed (by one).
llvm-svn: 83952
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 42de9fb..722d002 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -189,10 +189,12 @@
/// labels inside getIDForAddrOfLabel().
std::map<const LabelStmt*, unsigned> LabelIDs;
- /// IndirectSwitches - Record the list of switches for indirect
- /// gotos. Emission of the actual switching code needs to be delayed until all
- /// AddrLabelExprs have been seen.
- std::vector<llvm::SwitchInst*> IndirectSwitches;
+ /// 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;
/// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
/// decls.
@@ -555,6 +557,7 @@
static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant *Elts);
unsigned GetIDForAddrOfLabel(const LabelStmt *L);
+ llvm::BasicBlock *GetIndirectGotoBlock();
/// EmitMemSetToZero - Generate code to memset a value of the given type to 0.
void EmitMemSetToZero(llvm::Value *DestPtr, QualType Ty);
@@ -1014,10 +1017,6 @@
llvm::BasicBlock *FalseBlock);
private:
- /// EmitIndirectSwitches - Emit code for all of the switch
- /// instructions in IndirectSwitches.
- void EmitIndirectSwitches();
-
void EmitReturnOfRValue(RValue RV, QualType Ty);
/// ExpandTypeFromArgs - Reconstruct a structure of type \arg Ty