Make sure that landing pad entries in the EH call site table are in the proper

order for SjLj style exception handling.

llvm-svn: 94055
This commit is contained in:
Jim Grosbach 2010-01-21 00:43:30 +00:00
parent 7a77eae2f3
commit e029a6a5ed
6 changed files with 54 additions and 5 deletions

View File

@ -113,7 +113,11 @@ class MachineModuleInfo : public ImmutablePass {
// LandingPads - List of LandingPadInfo describing the landing pad information
// in the current function.
std::vector<LandingPadInfo> LandingPads;
// Map of invoke call site index values to associated begin EH_LABEL for
// the current function.
DenseMap<unsigned, unsigned> CallSiteMap;
// TypeInfos - List of C++ TypeInfo used in the current function.
//
std::vector<GlobalVariable *> TypeInfos;
@ -301,7 +305,19 @@ public:
const std::vector<LandingPadInfo> &getLandingPads() const {
return LandingPads;
}
/// setCallSiteBeginLabel - Map the begin label for a call site
void setCallSiteBeginLabel(unsigned BeginLabel, unsigned Site) {
CallSiteMap[BeginLabel] = Site;
}
/// getCallSiteBeginLabel - Get the call site number for a begin label
unsigned getCallSiteBeginLabel(unsigned BeginLabel) {
assert(CallSiteMap.count(BeginLabel) &&
"Missing call site number for EH_LABEL!");
return CallSiteMap[BeginLabel];
}
/// getTypeInfos - Return a reference to the C++ typeinfo for the current
/// function.
const std::vector<GlobalVariable *> &getTypeInfos() const {

View File

@ -24,6 +24,7 @@
#include "llvm/Argument.h"
#include "llvm/Attributes.h"
#include "llvm/Support/Compiler.h"
#include "llvm/ADT/DenseMap.h"
namespace llvm {
@ -86,6 +87,8 @@ private:
mutable ArgumentListType ArgumentList; ///< The formal arguments
ValueSymbolTable *SymTab; ///< Symbol table of args/instructions
AttrListPtr AttributeList; ///< Parameter attributes
DenseMap<Instruction*, unsigned>
CallSiteNumbering; ///< SjLj EH call site numbering
// HasLazyArguments is stored in Value::SubclassData.
/*bool HasLazyArguments;*/
@ -165,7 +168,19 @@ public:
setValueSubclassData((getSubclassDataFromValue() & 1) |
(static_cast<unsigned>(CC) << 1));
}
/// setCallSiteNumber - Set the call site number mapping for an invoke
/// in the function
void setCallSiteNumber(Instruction *II, unsigned Num) {
CallSiteNumbering[II] = Num;
}
/// getCallSiteNumber - Get the call site number for an invoke instruction
unsigned getCallSiteNumber(Instruction *II) {
if (CallSiteNumbering.count(II) == 0) return 0;
return CallSiteNumbering[II];
}
/// getAttributes - Return the attribute list for this Function.
///
const AttrListPtr &getAttributes() const { return AttributeList; }

View File

@ -590,7 +590,16 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
}
// Otherwise, create a new call-site.
CallSites.push_back(Site);
if (MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf)
CallSites.push_back(Site);
else {
// SjLj EH must maintain the call sites in the order assigned
// to them by the SjLjPrepare pass.
unsigned SiteNo = MMI->getCallSiteBeginLabel(BeginLabel);
if (CallSites.size() < SiteNo)
CallSites.resize(SiteNo);
CallSites[SiteNo - 1] = Site;
}
PreviousIsInvoke = true;
} else {
// Create a gap.

View File

@ -71,6 +71,7 @@ void MachineModuleInfo::EndFunction() {
// Clean up exception info.
LandingPads.clear();
CallSiteMap.clear();
TypeInfos.clear();
FilterIds.clear();
FilterEnds.clear();

View File

@ -5049,6 +5049,12 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
// used to detect deletion of the invoke via the MachineModuleInfo.
BeginLabel = MMI->NextLabelID();
// Keep track of which landing pads go with which invokes. SjLj uses
// this to maintain the ordering of pads in the LSDA. Dwarf ignores it.
Function *F = LandingPad->getParent()->getFunction();
MMI->setCallSiteBeginLabel(BeginLabel,
F->getCallSiteNumber(CS.getInstruction()));
// Both PendingLoads and PendingExports must be flushed here;
// this call might not return.
(void)getRoot();

View File

@ -474,8 +474,10 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) {
// At this point, we are all set up, update the invoke instructions
// to mark their call_site values, and fill in the dispatch switch
// accordingly.
for (unsigned i = 0, e = Invokes.size(); i != e; ++i)
for (unsigned i = 0, e = Invokes.size(); i != e; ++i) {
F.setCallSiteNumber(Invokes[i], i+1);
markInvokeCallSite(Invokes[i], i+1, CallSite, DispatchSwitch);
}
// The front end has likely added calls to _Unwind_Resume. We need
// to find those calls and mark the call_site as -1 immediately prior.