Newer
Older
Bill Wendling
committed
for (unsigned I = 0; I != TyInfoSize; ++I)
IdsInFilter[I] = getTypeIDFor(TyInfo[I]);
Bill Wendling
committed
LP.TypeIds.push_back(getFilterIDFor(IdsInFilter));
/// addCleanup - Add a cleanup action for a landing pad.
///
void MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) {
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
LP.TypeIds.push_back(0);
}
/// TidyLandingPads - Remap landing pad labels and remove any deleted landing
/// pads.
void MachineModuleInfo::TidyLandingPads() {
for (unsigned i = 0; i != LandingPads.size(); ) {
LandingPadInfo &LandingPad = LandingPads[i];
LandingPad.LandingPadLabel = MappedLabel(LandingPad.LandingPadLabel);
Anton Korobeynikov
committed
// Special case: we *should* emit LPs with null LP MBB. This indicates
// "nounwind" case.
Anton Korobeynikov
committed
if (!LandingPad.LandingPadLabel && LandingPad.LandingPadBlock) {
LandingPads.erase(LandingPads.begin() + i);
continue;
}
Bill Wendling
committed
for (unsigned j = 0; j != LandingPads[i].BeginLabels.size(); ) {
unsigned BeginLabel = MappedLabel(LandingPad.BeginLabels[j]);
unsigned EndLabel = MappedLabel(LandingPad.EndLabels[j]);
if (!BeginLabel || !EndLabel) {
LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j);
LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j);
continue;
}
LandingPad.BeginLabels[j] = BeginLabel;
LandingPad.EndLabels[j] = EndLabel;
++j;
}
// Remove landing pads with no try-ranges.
if (LandingPads[i].BeginLabels.empty()) {
LandingPads.erase(LandingPads.begin() + i);
continue;
}
// If there is no landing pad, ensure that the list of typeids is empty.
// If the only typeid is a cleanup, this is the same as having no typeids.
if (!LandingPad.LandingPadBlock ||
(LandingPad.TypeIds.size() == 1 && !LandingPad.TypeIds[0]))
LandingPad.TypeIds.clear();
++i;
}
}
/// getTypeIDFor - Return the type id for the specified typeinfo. This is
/// function wide.
unsigned MachineModuleInfo::getTypeIDFor(GlobalVariable *TI) {
Bill Wendling
committed
for (unsigned i = 0, e = TypeInfos.size(); i != e; ++i)
if (TypeInfos[i] == TI)
return i + 1;
TypeInfos.push_back(TI);
return TypeInfos.size();
}
/// getFilterIDFor - Return the filter id for the specified typeinfos. This is
/// function wide.
int MachineModuleInfo::getFilterIDFor(std::vector<unsigned> &TyIds) {
// If the new filter coincides with the tail of an existing filter, then
// re-use the existing filter. Folding filters more than this requires
// re-ordering filters and/or their elements - probably not worth it.
for (std::vector<unsigned>::iterator I = FilterEnds.begin(),
E = FilterEnds.end(); I != E; ++I) {
while (i && j)
if (FilterIds[--i] != TyIds[--j])
goto try_next;
if (!j)
// The new filter coincides with range [i, end) of the existing filter.
return -(1 + i);
try_next:;
}
// Add the new filter.
int FilterID = -(1 + FilterIds.size());
FilterIds.reserve(FilterIds.size() + TyIds.size() + 1);
Bill Wendling
committed
for (unsigned I = 0, N = TyIds.size(); I != N; ++I)
FilterIds.push_back(TyIds[I]);
Bill Wendling
committed
FilterIds.push_back(0); // terminator
return FilterID;
}
Anton Korobeynikov
committed
/// getPersonality - Return the personality function for the current function.
Function *MachineModuleInfo::getPersonality() const {
// FIXME: Until PR1414 will be fixed, we're using 1 personality function per
Anton Korobeynikov
committed
// function
return !LandingPads.empty() ? LandingPads[0].Personality : NULL;
Anton Korobeynikov
committed
/// getPersonalityIndex - Return unique index for current personality
/// function. NULL personality function should always get zero index.
unsigned MachineModuleInfo::getPersonalityIndex() const {
Anton Korobeynikov
committed
const Function* Personality = NULL;
// Scan landing pads. If there is at least one non-NULL personality - use it.
Bill Wendling
committed
for (unsigned i = 0, e = LandingPads.size(); i != e; ++i)
Anton Korobeynikov
committed
if (LandingPads[i].Personality) {
Personality = LandingPads[i].Personality;
break;
}
Bill Wendling
committed
for (unsigned i = 0, e = Personalities.size(); i < e; ++i)
Anton Korobeynikov
committed
if (Personalities[i] == Personality)
return i;
// This should never happen
assert(0 && "Personality function should be set!");
return 0;
}
Jim Laskey
committed
//===----------------------------------------------------------------------===//
/// DebugLabelFolding pass - This pass prunes out redundant labels. This allows
/// a info consumer to determine if the range of two labels is empty, by seeing
/// if the labels map to the same reduced label.
Jim Laskey
committed
namespace llvm {
struct DebugLabelFolder : public MachineFunctionPass {
DebugLabelFolder() : MachineFunctionPass((intptr_t)&ID) {}
Jim Laskey
committed
virtual bool runOnMachineFunction(MachineFunction &MF);
virtual const char *getPassName() const { return "Label Folder"; }
Jim Laskey
committed
};
Jim Laskey
committed
bool DebugLabelFolder::runOnMachineFunction(MachineFunction &MF) {
// Get machine module info.
MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>();
if (!MMI) return false;
Jim Laskey
committed
// Track if change is made.
bool MadeChange = false;
// No prior label to begin.
unsigned PriorLabel = 0;
// Iterate through basic blocks.
for (MachineFunction::iterator BB = MF.begin(), E = MF.end();
BB != E; ++BB) {
// Iterate through instructions.
for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
Evan Cheng
committed
if (I->isDebugLabel()) {
Jim Laskey
committed
// The label ID # is always operand #0, an immediate.
unsigned NextLabel = I->getOperand(0).getImm();
// If there was an immediate prior label.
if (PriorLabel) {
// Remap the current label to prior label.
Jim Laskey
committed
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
// Delete the current label.
I = BB->erase(I);
// Indicate a change has been made.
MadeChange = true;
continue;
} else {
// Start a new round.
PriorLabel = NextLabel;
}
} else {
// No consecutive labels.
PriorLabel = 0;
}
++I;
}
}
return MadeChange;
}
FunctionPass *createDebugLabelFoldingPass() { return new DebugLabelFolder(); }
}