Newer
Older
case DW_TAG_arg_variable:
case DW_TAG_return_variable:
return true;
default: break;
}
return false;
}
/// ApplyToFields - Target the visitor to the fields of the VariableDesc.
///
void VariableDesc::ApplyToFields(DIVisitor *Visitor) {
DebugInfoDesc::ApplyToFields(Visitor);
Visitor->Apply(Context);
Visitor->Apply(Name);
Visitor->Apply(Line);
}
/// getDescString - Return a string used to compose global names and labels.
///
const char *VariableDesc::getDescString() const {
return "llvm.dbg.variable";
}
/// getTypeString - Return a string used to label this descriptor's type.
///
const char *VariableDesc::getTypeString() const {
return "llvm.dbg.variable.type";
}
#ifndef NDEBUG
void VariableDesc::dump() {
cerr << getDescString() << " "
<< "Version(" << getVersion() << "), "
<< "Tag(" << getTag() << "), "
<< "Context(" << Context << "), "
<< "Name(\"" << Name << "\"), "
<< "File(" << File << "), "
<< "Line(" << Line << "), "
<< "TyDesc(" << TyDesc << ")\n";
}
#endif
//===----------------------------------------------------------------------===//
Jim Laskey
committed
GlobalDesc::GlobalDesc(unsigned T)
: AnchoredDesc(T)
, Context(0)
, Name("")
, FullName("")
, LinkageName("")
Jim Laskey
committed
, TyDesc(NULL)
, IsStatic(false)
, IsDefinition(false)
{}
/// ApplyToFields - Target the visitor to the fields of the global.
Jim Laskey
committed
void GlobalDesc::ApplyToFields(DIVisitor *Visitor) {
AnchoredDesc::ApplyToFields(Visitor);
Visitor->Apply(Context);
Visitor->Apply(Name);
Visitor->Apply(FullName);
Visitor->Apply(LinkageName);
Visitor->Apply(IsStatic);
Visitor->Apply(IsDefinition);
Jim Laskey
committed
}
//===----------------------------------------------------------------------===//
GlobalVariableDesc::GlobalVariableDesc()
: GlobalDesc(DW_TAG_variable)
Jim Laskey
committed
, Global(NULL)
{}
// Implement isa/cast/dyncast.
bool GlobalVariableDesc::classof(const DebugInfoDesc *D) {
return D->getTag() == DW_TAG_variable;
}
Jim Laskey
committed
/// ApplyToFields - Target the visitor to the fields of the GlobalVariableDesc.
///
void GlobalVariableDesc::ApplyToFields(DIVisitor *Visitor) {
GlobalDesc::ApplyToFields(Visitor);
}
Jim Laskey
committed
/// getDescString - Return a string used to compose global names and labels.
///
Jim Laskey
committed
const char *GlobalVariableDesc::getDescString() const {
return "llvm.dbg.global_variable";
}
/// getTypeString - Return a string used to label this descriptors type.
///
const char *GlobalVariableDesc::getTypeString() const {
return "llvm.dbg.global_variable.type";
}
/// getAnchorString - Return a string used to label this descriptor's anchor.
///
const char *GlobalVariableDesc::AnchorString = "llvm.dbg.global_variables";
Jim Laskey
committed
const char *GlobalVariableDesc::getAnchorString() const {
}
#ifndef NDEBUG
void GlobalVariableDesc::dump() {
cerr << getDescString() << " "
<< "Version(" << getVersion() << "), "
<< "Tag(" << getTag() << "), "
<< "Anchor(" << getAnchor() << "), "
<< "Name(\"" << getName() << "\"), "
<< "FullName(\"" << getFullName() << "\"), "
<< "LinkageName(\"" << getLinkageName() << "\"), "
<< "File(" << getFile() << "),"
<< "Line(" << getLine() << "),"
<< "Type(" << getType() << "), "
<< "IsStatic(" << (isStatic() ? "true" : "false") << "), "
<< "IsDefinition(" << (isDefinition() ? "true" : "false") << "), "
<< "Global(" << Global << ")\n";
}
#endif
//===----------------------------------------------------------------------===//
Jim Laskey
committed
SubprogramDesc::SubprogramDesc()
: GlobalDesc(DW_TAG_subprogram)
Jim Laskey
committed
{}
// Implement isa/cast/dyncast.
bool SubprogramDesc::classof(const DebugInfoDesc *D) {
return D->getTag() == DW_TAG_subprogram;
}
/// ApplyToFields - Target the visitor to the fields of the
/// SubprogramDesc.
void SubprogramDesc::ApplyToFields(DIVisitor *Visitor) {
Jim Laskey
committed
GlobalDesc::ApplyToFields(Visitor);
}
/// getDescString - Return a string used to compose global names and labels.
///
const char *SubprogramDesc::getDescString() const {
return "llvm.dbg.subprogram";
}
/// getTypeString - Return a string used to label this descriptors type.
///
const char *SubprogramDesc::getTypeString() const {
return "llvm.dbg.subprogram.type";
Jim Laskey
committed
/// getAnchorString - Return a string used to label this descriptor's anchor.
///
const char *SubprogramDesc::AnchorString = "llvm.dbg.subprograms";
Jim Laskey
committed
const char *SubprogramDesc::getAnchorString() const {
}
#ifndef NDEBUG
void SubprogramDesc::dump() {
cerr << getDescString() << " "
<< "Version(" << getVersion() << "), "
<< "Tag(" << getTag() << "), "
<< "Anchor(" << getAnchor() << "), "
<< "Name(\"" << getName() << "\"), "
<< "FullName(\"" << getFullName() << "\"), "
<< "LinkageName(\"" << getLinkageName() << "\"), "
<< "File(" << getFile() << "),"
<< "Line(" << getLine() << "),"
<< "Type(" << getType() << "), "
<< "IsStatic(" << (isStatic() ? "true" : "false") << "), "
<< "IsDefinition(" << (isDefinition() ? "true" : "false") << ")\n";
}
#endif
//===----------------------------------------------------------------------===//
BlockDesc::BlockDesc()
: DebugInfoDesc(DW_TAG_lexical_block)
, Context(NULL)
{}
// Implement isa/cast/dyncast.
bool BlockDesc::classof(const DebugInfoDesc *D) {
return D->getTag() == DW_TAG_lexical_block;
}
/// ApplyToFields - Target the visitor to the fields of the BlockDesc.
///
void BlockDesc::ApplyToFields(DIVisitor *Visitor) {
DebugInfoDesc::ApplyToFields(Visitor);
Visitor->Apply(Context);
}
/// getDescString - Return a string used to compose global names and labels.
///
const char *BlockDesc::getDescString() const {
return "llvm.dbg.block";
}
/// getTypeString - Return a string used to label this descriptors type.
///
const char *BlockDesc::getTypeString() const {
return "llvm.dbg.block.type";
}
#ifndef NDEBUG
void BlockDesc::dump() {
cerr << getDescString() << " "
<< "Version(" << getVersion() << "), "
<< "Tag(" << getTag() << "),"
<< "Context(" << Context << ")\n";
}
#endif
//===----------------------------------------------------------------------===//
DebugInfoDesc *DIDeserializer::Deserialize(Value *V) {
Jim Laskey
committed
return Deserialize(getGlobalVariable(V));
}
DebugInfoDesc *DIDeserializer::Deserialize(GlobalVariable *GV) {
Jim Laskey
committed
// Handle NULL.
if (!GV) return NULL;
// Check to see if it has been already deserialized.
DebugInfoDesc *&Slot = GlobalDescs[GV];
if (Slot) return Slot;
// Get the Tag from the global.
unsigned Tag = DebugInfoDesc::TagFromGlobal(GV);
// Create an empty instance of the correct sort.
Slot = DebugInfoDesc::DescFactory(Tag);
// If not a user defined descriptor.
if (Slot) {
// Deserialize the fields.
DIDeserializeVisitor DRAM(*this, GV);
DRAM.ApplyToFields(Slot);
}
return Slot;
}
//===----------------------------------------------------------------------===//
/// getStrPtrType - Return a "sbyte *" type.
///
const PointerType *DISerializer::getStrPtrType() {
// If not already defined.
if (!StrPtrTy) {
// Construct the pointer to signed bytes.
}
return StrPtrTy;
}
/// getEmptyStructPtrType - Return a "{ }*" type.
///
const PointerType *DISerializer::getEmptyStructPtrType() {
// If not already defined.
if (!EmptyStructPtrTy) {
// Construct the empty structure type.
const StructType *EmptyStructTy =
StructType::get(std::vector<const Type*>());
// Construct the pointer to empty structure type.
EmptyStructPtrTy = PointerType::get(EmptyStructTy);
}
return EmptyStructPtrTy;
}
/// getTagType - Return the type describing the specified descriptor (via tag.)
///
const StructType *DISerializer::getTagType(DebugInfoDesc *DD) {
// Attempt to get the previously defined type.
StructType *&Ty = TagTypes[DD->getTag()];
// If not already defined.
if (!Ty) {
// Set up fields vector.
std::vector<const Type*> Fields;
Jim Laskey
committed
// Get types of fields.
GTAM.ApplyToFields(DD);
// Construct structured type.
Ty = StructType::get(Fields);
// Register type name with module.
Jim Laskey
committed
M->addTypeName(DD->getTypeString(), Ty);
}
return Ty;
}
/// getString - Construct the string as constant string global.
///
Jim Laskey
committed
Constant *DISerializer::getString(const std::string &String) {
// Check string cache for previous edition.
Jim Laskey
committed
Constant *&Slot = StringCache[String];
// Return Constant if previously defined.
if (Slot) return Slot;
// If empty string then use a sbyte* null instead.
if (String.empty()) {
Slot = ConstantPointerNull::get(getStrPtrType());
} else {
// Construct string as an llvm constant.
Constant *ConstStr = ConstantArray::get(String);
// Otherwise create and return a new string global.
GlobalVariable *StrGV = new GlobalVariable(ConstStr->getType(), true,
GlobalVariable::InternalLinkage,
Devang Patel
committed
ConstStr, ".str", M);
StrGV->setSection("llvm.metadata");
// Convert to generic string pointer.
Slot = ConstantExpr::getBitCast(StrGV, getStrPtrType());
Jim Laskey
committed
return Slot;
}
/// Serialize - Recursively cast the specified descriptor into a GlobalVariable
/// so that it can be serialized to a .bc or .ll file.
GlobalVariable *DISerializer::Serialize(DebugInfoDesc *DD) {
// Check if the DebugInfoDesc is already in the map.
GlobalVariable *&Slot = DescGlobals[DD];
// See if DebugInfoDesc exists, if so return prior GlobalVariable.
if (Slot) return Slot;
// Get the type associated with the Tag.
const StructType *Ty = getTagType(DD);
// Create the GlobalVariable early to prevent infinite recursion.
Jim Laskey
committed
GlobalVariable *GV = new GlobalVariable(Ty, true, DD->getLinkage(),
NULL, DD->getDescString(), M);
GV->setSection("llvm.metadata");
// Insert new GlobalVariable in DescGlobals map.
Slot = GV;
// Set up elements vector
std::vector<Constant*> Elements;
Jim Laskey
committed
// Add fields.
SRAM.ApplyToFields(DD);
// Set the globals initializer.
GV->setInitializer(ConstantStruct::get(Ty, Elements));
return GV;
}
//===----------------------------------------------------------------------===//
/// Verify - Return true if the GlobalVariable appears to be a valid
/// serialization of a DebugInfoDesc.
Jim Laskey
committed
bool DIVerifier::Verify(Value *V) {
return !V || Verify(getGlobalVariable(V));
Jim Laskey
committed
}
bool DIVerifier::Verify(GlobalVariable *GV) {
// NULLs are valid.
if (!GV) return true;
// Check prior validity.
unsigned &ValiditySlot = Validity[GV];
// If visited before then use old state.
if (ValiditySlot) return ValiditySlot == Valid;
// Assume validity for the time being (recursion.)
ValiditySlot = Valid;
// Make sure the global is internal or link once (anchor.)
if (GV->getLinkage() != GlobalValue::InternalLinkage &&
GV->getLinkage() != GlobalValue::LinkOnceLinkage) {
ValiditySlot = Invalid;
return false;
}
unsigned Tag = DebugInfoDesc::TagFromGlobal(GV);
// Check for user defined descriptors.
if (Tag == DW_TAG_invalid) {
ValiditySlot = Valid;
return true;
}
// Get the Version.
unsigned Version = DebugInfoDesc::VersionFromGlobal(GV);
// Check for version mismatch.
if (Version != LLVMDebugVersion) {
ValiditySlot = Invalid;
return false;
}
// Construct an empty DebugInfoDesc.
DebugInfoDesc *DD = DebugInfoDesc::DescFactory(Tag);
// Allow for user defined descriptors.
if (!DD) return true;
// Get the initializer constant.
ConstantStruct *CI = cast<ConstantStruct>(GV->getInitializer());
// Get the operand count.
unsigned N = CI->getNumOperands();
// Get the field count.
unsigned &CountSlot = Counts[Tag];
if (!CountSlot) {
// Check the operand count to the field count
CTAM.ApplyToFields(DD);
CountSlot = CTAM.getCount();
// Field count must be at most equal operand count.
if (CountSlot > N) {
ValiditySlot = Invalid;
return false;
}
// Check each field for valid type.
VRAM.ApplyToFields(DD);
// Release empty DebugInfoDesc.
delete DD;
// If fields are not valid.
if (!VRAM.isValid()) {
ValiditySlot = Invalid;
return false;
}
return true;
}
//===----------------------------------------------------------------------===//
DebugScope::~DebugScope() {
for (unsigned i = 0, N = Scopes.size(); i < N; ++i) delete Scopes[i];
for (unsigned j = 0, M = Variables.size(); j < M; ++j) delete Variables[j];
}
//===----------------------------------------------------------------------===//
: ImmutablePass((intptr_t)&ID)
, DR()
, VR()
, CompileUnits()
, Directories()
, SourceFiles()
, Lines()
Jim Laskey
committed
, LabelIDList()
, ScopeMap()
, RootScope(NULL)
Anton Korobeynikov
committed
, Personalities()
, CallsEHReturn(0)
, CallsUnwindInit(0)
Anton Korobeynikov
committed
{
// Always emit "no personality" info
Personalities.push_back(NULL);
}
}
/// doInitialization - Initialize the state for a new module.
///
return false;
}
/// doFinalization - Tear down the state after completion of a module.
///
return false;
}
/// BeginFunction - Begin gathering function meta information.
// Clean up scope information.
if (RootScope) {
delete RootScope;
ScopeMap.clear();
RootScope = NULL;
}
// Clean up line info.
Lines.clear();
// Clean up frame info.
FrameMoves.clear();
// Clean up exception info.
LandingPads.clear();
TypeInfos.clear();
FilterIds.clear();
FilterEnds.clear();
CallsEHReturn = 0;
CallsUnwindInit = 0;
/// getDescFor - Convert a Value to a debug information descriptor.
Jim Laskey
committed
///
// FIXME - use new Value type when available.
Jim Laskey
committed
return DR.Deserialize(V);
}
/// Verify - Verify that a Value is debug information descriptor.
///
Jim Laskey
committed
return VR.Verify(V);
}
/// AnalyzeModule - Scan the module for global debug information.
///
SetupCompileUnits(M);
}
/// needsFrameInfo - Returns true if we need to gather callee-saved register
/// move info for the frame.
bool MachineModuleInfo::needsFrameInfo() const {
return hasDebugInfo() || ExceptionHandling;
}
/// SetupCompileUnits - Set up the unique vector of compile units.
///
std::vector<CompileUnitDesc *>CU = getAnchoredDescriptors<CompileUnitDesc>(M);
for (unsigned i = 0, N = CU.size(); i < N; i++) {
CompileUnits.insert(CU[i]);
}
}
/// getCompileUnits - Return a vector of debug compile units.
///
const UniqueVector<CompileUnitDesc *> MachineModuleInfo::getCompileUnits()const{
return CompileUnits;
}
/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the
/// named GlobalVariable.
std::vector<GlobalVariable*>
MachineModuleInfo::getGlobalVariablesUsing(Module &M,
const std::string &RootName) {
return ::getGlobalVariablesUsing(M, RootName);
}
/// RecordLabel - Records location information and associates it with a
/// debug label. Returns a unique label ID used to generate a label and
/// provide correspondence to the source line list.
unsigned MachineModuleInfo::RecordLabel(unsigned Line, unsigned Column,
unsigned Source) {
unsigned ID = NextLabelID();
Lines.push_back(SourceLineInfo(Line, Column, Source, ID));
return ID;
}
/// RecordSource - Register a source file with debug info. Returns an source
/// ID.
unsigned MachineModuleInfo::RecordSource(const std::string &Directory,
const std::string &Source) {
unsigned DirectoryID = Directories.insert(Directory);
return SourceFiles.insert(SourceFileInfo(DirectoryID, Source));
}
unsigned MachineModuleInfo::RecordSource(const CompileUnitDesc *CompileUnit) {
return RecordSource(CompileUnit->getDirectory(),
CompileUnit->getFileName());
}
/// RecordRegionStart - Indicate the start of a region.
///
// FIXME - need to be able to handle split scopes because of bb cloning.
DebugInfoDesc *ScopeDesc = DR.Deserialize(V);
DebugScope *Scope = getOrCreateScope(ScopeDesc);
unsigned ID = NextLabelID();
if (!Scope->getStartLabelID()) Scope->setStartLabelID(ID);
return ID;
}
/// RecordRegionEnd - Indicate the end of a region.
///
// FIXME - need to be able to handle split scopes because of bb cloning.
DebugInfoDesc *ScopeDesc = DR.Deserialize(V);
DebugScope *Scope = getOrCreateScope(ScopeDesc);
unsigned ID = NextLabelID();
Scope->setEndLabelID(ID);
return ID;
}
/// RecordVariable - Indicate the declaration of a local variable.
///
void MachineModuleInfo::RecordVariable(Value *V, unsigned FrameIndex) {
VariableDesc *VD = cast<VariableDesc>(DR.Deserialize(V));
DebugScope *Scope = getOrCreateScope(VD->getContext());
DebugVariable *DV = new DebugVariable(VD, FrameIndex);
Scope->AddVariable(DV);
}
/// getOrCreateScope - Returns the scope associated with the given descriptor.
///
DebugScope *MachineModuleInfo::getOrCreateScope(DebugInfoDesc *ScopeDesc) {
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
DebugScope *&Slot = ScopeMap[ScopeDesc];
if (!Slot) {
// FIXME - breaks down when the context is an inlined function.
DebugInfoDesc *ParentDesc = NULL;
if (BlockDesc *Block = dyn_cast<BlockDesc>(ScopeDesc)) {
ParentDesc = Block->getContext();
}
DebugScope *Parent = ParentDesc ? getOrCreateScope(ParentDesc) : NULL;
Slot = new DebugScope(Parent, ScopeDesc);
if (Parent) {
Parent->AddScope(Slot);
} else if (RootScope) {
// FIXME - Add inlined function scopes to the root so we can delete
// them later. Long term, handle inlined functions properly.
RootScope->AddScope(Slot);
} else {
// First function is top level function.
RootScope = Slot;
}
}
return Slot;
}
//===-EH-------------------------------------------------------------------===//
/// getOrCreateLandingPadInfo - Find or create an LandingPadInfo for the
/// specified MachineBasicBlock.
LandingPadInfo &MachineModuleInfo::getOrCreateLandingPadInfo
(MachineBasicBlock *LandingPad) {
unsigned N = LandingPads.size();
for (unsigned i = 0; i < N; ++i) {
LandingPadInfo &LP = LandingPads[i];
if (LP.LandingPadBlock == LandingPad)
return LP;
}
LandingPads.push_back(LandingPadInfo(LandingPad));
return LandingPads[N];
}
/// addInvoke - Provide the begin and end labels of an invoke style call and
/// associate it with a try landing pad block.
void MachineModuleInfo::addInvoke(MachineBasicBlock *LandingPad,
unsigned BeginLabel, unsigned EndLabel) {
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
LP.BeginLabels.push_back(BeginLabel);
LP.EndLabels.push_back(EndLabel);
}
/// addLandingPad - Provide the label of a try LandingPad block.
///
unsigned MachineModuleInfo::addLandingPad(MachineBasicBlock *LandingPad) {
unsigned LandingPadLabel = NextLabelID();
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
LP.LandingPadLabel = LandingPadLabel;
return LandingPadLabel;
}
/// addPersonality - Provide the personality function for the exception
/// information.
void MachineModuleInfo::addPersonality(MachineBasicBlock *LandingPad,
Anton Korobeynikov
committed
Function *Personality) {
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
Anton Korobeynikov
committed
LP.Personality = Personality;
Anton Korobeynikov
committed
for (unsigned i = 0; i < Personalities.size(); ++i)
if (Personalities[i] == Personality)
return;
Personalities.push_back(Personality);
}
/// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
///
void MachineModuleInfo::addCatchTypeInfo(MachineBasicBlock *LandingPad,
std::vector<GlobalVariable *> &TyInfo) {
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
for (unsigned N = TyInfo.size(); N; --N)
LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1]));
/// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
void MachineModuleInfo::addFilterTypeInfo(MachineBasicBlock *LandingPad,
std::vector<GlobalVariable *> &TyInfo) {
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
std::vector<unsigned> IdsInFilter (TyInfo.size());
for (unsigned I = 0, E = TyInfo.size(); I != E; ++I)
IdsInFilter[I] = getTypeIDFor(TyInfo[I]);
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);
if (!LandingPad.LandingPadBlock)
// Must not have cleanups if no landing pad.
LandingPad.TypeIds.clear();
Anton Korobeynikov
committed
// Special case: we *should* emit LPs with null LP MBB. This indicates
// "rethrow" case.
if (!LandingPad.LandingPadLabel && LandingPad.LandingPadBlock) {
LandingPads.erase(LandingPads.begin() + i);
continue;
}
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;
}
++i;
}
}
/// getTypeIDFor - Return the type id for the specified typeinfo. This is
/// function wide.
unsigned MachineModuleInfo::getTypeIDFor(GlobalVariable *TI) {
for (unsigned i = 0, N = TypeInfos.size(); i != N; ++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) {
unsigned i = *I, j = TyIds.size();
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);
for (unsigned I = 0, N = TyIds.size(); I != N; ++I)
FilterIds.push_back(TyIds[I]);
FilterEnds.push_back(FilterIds.size());
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.
for (unsigned i = 0; i != LandingPads.size(); ++i)
if (LandingPads[i].Personality) {
Personality = LandingPads[i].Personality;
break;
}
Anton Korobeynikov
committed
for (unsigned i = 0; i < Personalities.size(); ++i) {
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
// Get target instruction info.
const TargetInstrInfo *TII = MF.getTarget().getInstrInfo();
if (!TII) return false;
// 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; ) {
if ((unsigned)I->getOpcode() == TargetInstrInfo::LABEL) {
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
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
// 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(); }
}