2007-01-27 05:38:26 +08:00
|
|
|
//===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===//
|
2006-01-04 21:36:38 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 04:36:04 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2006-01-04 21:36:38 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2007-01-27 05:38:26 +08:00
|
|
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
2006-01-04 21:36:38 +08:00
|
|
|
|
2006-01-27 04:21:46 +08:00
|
|
|
#include "llvm/Constants.h"
|
2008-06-30 15:31:25 +08:00
|
|
|
#include "llvm/Analysis/ValueTracking.h"
|
2006-11-08 03:33:46 +08:00
|
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
|
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
2008-09-23 06:21:38 +08:00
|
|
|
#include "llvm/CodeGen/Passes.h"
|
2006-11-08 03:33:46 +08:00
|
|
|
#include "llvm/Target/TargetInstrInfo.h"
|
|
|
|
#include "llvm/Target/TargetMachine.h"
|
2007-01-30 07:40:33 +08:00
|
|
|
#include "llvm/Target/TargetOptions.h"
|
2006-01-27 04:21:46 +08:00
|
|
|
#include "llvm/DerivedTypes.h"
|
2006-02-06 23:33:21 +08:00
|
|
|
#include "llvm/GlobalVariable.h"
|
2006-01-27 04:21:46 +08:00
|
|
|
#include "llvm/Intrinsics.h"
|
|
|
|
#include "llvm/Instructions.h"
|
|
|
|
#include "llvm/Module.h"
|
|
|
|
#include "llvm/Support/Dwarf.h"
|
2009-07-12 04:10:48 +08:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2006-01-04 21:36:38 +08:00
|
|
|
using namespace llvm;
|
2006-03-02 04:39:36 +08:00
|
|
|
using namespace llvm::dwarf;
|
2006-01-04 21:36:38 +08:00
|
|
|
|
|
|
|
// Handle the Pass registration stuff necessary to use TargetData's.
|
2008-05-13 08:00:25 +08:00
|
|
|
static RegisterPass<MachineModuleInfo>
|
|
|
|
X("machinemoduleinfo", "Module Information");
|
2007-05-03 09:11:54 +08:00
|
|
|
char MachineModuleInfo::ID = 0;
|
2006-01-18 01:31:53 +08:00
|
|
|
|
2009-09-16 06:44:26 +08:00
|
|
|
// Out of line virtual method.
|
|
|
|
MachineModuleInfoImpl::~MachineModuleInfoImpl() {}
|
|
|
|
|
2006-01-27 04:21:46 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2009-08-27 05:27:09 +08:00
|
|
|
|
2007-01-27 05:38:26 +08:00
|
|
|
MachineModuleInfo::MachineModuleInfo()
|
2008-09-05 01:05:41 +08:00
|
|
|
: ImmutablePass(&ID)
|
2009-09-16 13:26:00 +08:00
|
|
|
, ObjFileMMI(0)
|
2007-07-14 22:06:15 +08:00
|
|
|
, CallsEHReturn(0)
|
|
|
|
, CallsUnwindInit(0)
|
2009-09-16 06:44:26 +08:00
|
|
|
, DbgInfoAvailable(false) {
|
2009-08-27 05:30:49 +08:00
|
|
|
// Always emit some info, by default "no personality" info.
|
2007-05-13 23:42:26 +08:00
|
|
|
Personalities.push_back(NULL);
|
|
|
|
}
|
2006-01-27 04:21:46 +08:00
|
|
|
|
2009-09-16 06:44:26 +08:00
|
|
|
MachineModuleInfo::~MachineModuleInfo() {
|
2009-09-16 13:26:00 +08:00
|
|
|
delete ObjFileMMI;
|
2006-01-27 04:21:46 +08:00
|
|
|
}
|
|
|
|
|
2007-01-27 05:38:26 +08:00
|
|
|
/// doInitialization - Initialize the state for a new module.
|
2006-01-05 06:28:25 +08:00
|
|
|
///
|
2007-01-27 05:38:26 +08:00
|
|
|
bool MachineModuleInfo::doInitialization() {
|
2006-01-05 06:28:25 +08:00
|
|
|
return false;
|
|
|
|
}
|
2006-01-04 21:36:38 +08:00
|
|
|
|
2007-01-27 05:38:26 +08:00
|
|
|
/// doFinalization - Tear down the state after completion of a module.
|
2006-01-05 06:28:25 +08:00
|
|
|
///
|
2007-01-27 05:38:26 +08:00
|
|
|
bool MachineModuleInfo::doFinalization() {
|
2006-01-05 06:28:25 +08:00
|
|
|
return false;
|
|
|
|
}
|
2006-01-27 04:21:46 +08:00
|
|
|
|
2007-01-27 05:38:26 +08:00
|
|
|
/// EndFunction - Discard function meta information.
|
2006-04-08 00:34:46 +08:00
|
|
|
///
|
2007-01-27 05:38:26 +08:00
|
|
|
void MachineModuleInfo::EndFunction() {
|
2006-04-08 00:34:46 +08:00
|
|
|
// Clean up frame info.
|
|
|
|
FrameMoves.clear();
|
2009-08-27 05:27:09 +08:00
|
|
|
|
2007-02-22 06:38:31 +08:00
|
|
|
// Clean up exception info.
|
|
|
|
LandingPads.clear();
|
|
|
|
TypeInfos.clear();
|
2007-06-03 00:53:42 +08:00
|
|
|
FilterIds.clear();
|
2007-07-05 23:15:01 +08:00
|
|
|
FilterEnds.clear();
|
2007-07-14 22:06:15 +08:00
|
|
|
CallsEHReturn = 0;
|
|
|
|
CallsUnwindInit = 0;
|
2009-10-09 04:41:17 +08:00
|
|
|
VariableDbgInfo.clear();
|
2006-04-08 00:34:46 +08:00
|
|
|
}
|
|
|
|
|
2006-01-27 04:21:46 +08:00
|
|
|
/// AnalyzeModule - Scan the module for global debug information.
|
|
|
|
///
|
2007-01-27 05:38:26 +08:00
|
|
|
void MachineModuleInfo::AnalyzeModule(Module &M) {
|
2009-07-20 14:14:25 +08:00
|
|
|
// Insert functions in the llvm.used array (but not llvm.compiler.used) into
|
|
|
|
// UsedFunctions.
|
2008-01-17 03:59:28 +08:00
|
|
|
GlobalVariable *GV = M.getGlobalVariable("llvm.used");
|
|
|
|
if (!GV || !GV->hasInitializer()) return;
|
|
|
|
|
|
|
|
// Should be an array of 'i8*'.
|
|
|
|
ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
|
|
|
|
if (InitList == 0) return;
|
|
|
|
|
2009-07-20 14:05:50 +08:00
|
|
|
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
|
|
|
|
if (Function *F =
|
|
|
|
dyn_cast<Function>(InitList->getOperand(i)->stripPointerCasts()))
|
|
|
|
UsedFunctions.insert(F);
|
2006-01-27 04:21:46 +08:00
|
|
|
}
|
|
|
|
|
2007-02-22 06:38:31 +08:00
|
|
|
//===-EH-------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// getOrCreateLandingPadInfo - Find or create an LandingPadInfo for the
|
|
|
|
/// specified MachineBasicBlock.
|
2008-07-04 06:53:42 +08:00
|
|
|
LandingPadInfo &MachineModuleInfo::getOrCreateLandingPadInfo
|
|
|
|
(MachineBasicBlock *LandingPad) {
|
2007-02-22 06:38:31 +08:00
|
|
|
unsigned N = LandingPads.size();
|
|
|
|
for (unsigned i = 0; i < N; ++i) {
|
2007-03-02 04:25:32 +08:00
|
|
|
LandingPadInfo &LP = LandingPads[i];
|
|
|
|
if (LP.LandingPadBlock == LandingPad)
|
|
|
|
return LP;
|
2007-02-22 06:38:31 +08:00
|
|
|
}
|
2009-08-27 05:27:09 +08:00
|
|
|
|
2007-02-22 06:38:31 +08:00
|
|
|
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) {
|
2007-03-02 04:25:32 +08:00
|
|
|
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
2007-05-11 06:34:59 +08:00
|
|
|
LP.BeginLabels.push_back(BeginLabel);
|
|
|
|
LP.EndLabels.push_back(EndLabel);
|
2007-02-22 06:38:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// addLandingPad - Provide the label of a try LandingPad block.
|
|
|
|
///
|
|
|
|
unsigned MachineModuleInfo::addLandingPad(MachineBasicBlock *LandingPad) {
|
|
|
|
unsigned LandingPadLabel = NextLabelID();
|
2007-03-02 04:25:32 +08:00
|
|
|
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
2009-08-27 05:27:09 +08:00
|
|
|
LP.LandingPadLabel = LandingPadLabel;
|
2007-02-22 06:38:31 +08:00
|
|
|
return LandingPadLabel;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// addPersonality - Provide the personality function for the exception
|
|
|
|
/// information.
|
|
|
|
void MachineModuleInfo::addPersonality(MachineBasicBlock *LandingPad,
|
2007-05-13 23:42:26 +08:00
|
|
|
Function *Personality) {
|
2007-03-02 04:25:32 +08:00
|
|
|
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
2007-05-13 23:42:26 +08:00
|
|
|
LP.Personality = Personality;
|
2007-05-13 06:36:25 +08:00
|
|
|
|
2008-07-04 06:53:42 +08:00
|
|
|
for (unsigned i = 0; i < Personalities.size(); ++i)
|
2007-05-13 23:42:26 +08:00
|
|
|
if (Personalities[i] == Personality)
|
|
|
|
return;
|
2009-08-27 05:27:09 +08:00
|
|
|
|
2009-08-27 05:30:49 +08:00
|
|
|
// If this is the first personality we're adding go
|
|
|
|
// ahead and add it at the beginning.
|
|
|
|
if (Personalities[0] == NULL)
|
|
|
|
Personalities[0] = Personality;
|
|
|
|
else
|
|
|
|
Personalities.push_back(Personality);
|
2007-02-22 06:38:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
|
|
|
|
///
|
|
|
|
void MachineModuleInfo::addCatchTypeInfo(MachineBasicBlock *LandingPad,
|
|
|
|
std::vector<GlobalVariable *> &TyInfo) {
|
2007-03-02 04:25:32 +08:00
|
|
|
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
2007-02-22 06:38:31 +08:00
|
|
|
for (unsigned N = TyInfo.size(); N; --N)
|
2007-03-02 04:25:32 +08:00
|
|
|
LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1]));
|
2007-02-22 06:38:31 +08:00
|
|
|
}
|
2007-06-03 00:53:42 +08:00
|
|
|
|
|
|
|
/// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
|
2007-03-02 04:25:32 +08:00
|
|
|
///
|
2007-06-03 00:53:42 +08:00
|
|
|
void MachineModuleInfo::addFilterTypeInfo(MachineBasicBlock *LandingPad,
|
|
|
|
std::vector<GlobalVariable *> &TyInfo) {
|
2007-03-02 04:25:32 +08:00
|
|
|
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
2008-07-08 05:41:57 +08:00
|
|
|
std::vector<unsigned> IdsInFilter(TyInfo.size());
|
2008-07-04 06:53:42 +08:00
|
|
|
for (unsigned I = 0, E = TyInfo.size(); I != E; ++I)
|
2007-06-03 00:53:42 +08:00
|
|
|
IdsInFilter[I] = getTypeIDFor(TyInfo[I]);
|
|
|
|
LP.TypeIds.push_back(getFilterIDFor(IdsInFilter));
|
2007-03-02 04:25:32 +08:00
|
|
|
}
|
|
|
|
|
There is an impedance matching problem between LLVM and
gcc exception handling: if an exception unwinds through
an invoke, then execution must branch to the invoke's
unwind target. We previously tried to enforce this by
appending a cleanup action to every selector, however
this does not always work correctly due to an optimization
in the C++ unwinding runtime: if only cleanups would be
run while unwinding an exception, then the program just
terminates without actually executing the cleanups, as
invoke semantics would require. I was hoping this
wouldn't be a problem, but in fact it turns out to be the
cause of all the remaining failures in the LLVM testsuite
(these also fail with -enable-correct-eh-support, so turning
on -enable-eh didn't make things worse!). Instead we need
to append a full-blown catch-all to the end of each
selector. The correct way of doing this depends on the
personality function, i.e. it is language dependent, so
can only be done by gcc. Thus this patch which generalizes
the eh.selector intrinsic so that it can handle all possible
kinds of action table entries (before it didn't accomodate
cleanups): now 0 indicates a cleanup, and filters have to be
specified using the number of type infos plus one rather than
the number of type infos. Related gcc patches will cause
Ada to pass a cleanup (0) to force the selector to always
fire, while C++ will use a C++ catch-all (null).
llvm-svn: 41484
2007-08-27 23:47:50 +08:00
|
|
|
/// addCleanup - Add a cleanup action for a landing pad.
|
|
|
|
///
|
|
|
|
void MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) {
|
|
|
|
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
|
|
|
LP.TypeIds.push_back(0);
|
|
|
|
}
|
|
|
|
|
2007-02-22 06:38:31 +08:00
|
|
|
/// 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);
|
2007-05-11 06:34:59 +08:00
|
|
|
|
2007-05-23 19:08:31 +08:00
|
|
|
// Special case: we *should* emit LPs with null LP MBB. This indicates
|
2007-12-19 15:36:31 +08:00
|
|
|
// "nounwind" case.
|
2007-05-23 19:08:31 +08:00
|
|
|
if (!LandingPad.LandingPadLabel && LandingPad.LandingPadBlock) {
|
2007-02-22 06:38:31 +08:00
|
|
|
LandingPads.erase(LandingPads.begin() + i);
|
|
|
|
continue;
|
|
|
|
}
|
Fix PR1628. When exception handling is turned on,
labels are generated bracketing each call (not just
invokes). This is used to generate entries in
the exception table required by the C++ personality.
However it gets in the way of tail-merging. This
patch solves the problem by no longer placing labels
around ordinary calls. Instead we generate entries
in the exception table that cover every instruction
in the function that wasn't covered by an invoke
range (the range given by the labels around the invoke).
As an optimization, such entries are only generated for
parts of the function that contain a call, since for
the moment those are the only instructions that can
throw an exception [1]. As a happy consequence, we
now get a smaller exception table, since the same
region can cover many calls. While there, I also
implemented folding of invoke ranges - successive
ranges are merged when safe to do so. Finally, if
a selector contains only a cleanup, there's a special
shorthand for it - place a 0 in the call-site entry.
I implemented this while there. As a result, the
exception table output (excluding filters) is now
optimal - it cannot be made smaller [2]. The
problem with throw filters is that folding them
optimally is hard, and the benefit of folding them is
minimal.
[1] I tested that having trapping instructions (eg
divide by zero) in such a region doesn't cause trouble.
[2] It could be made smaller with the help of higher
layers, eg by having branch folding reorder basic blocks
ending in invokes with the same landing pad so they
follow each other. I don't know if this is worth doing.
llvm-svn: 41718
2007-09-05 19:27:52 +08:00
|
|
|
|
2008-07-04 06:53:42 +08:00
|
|
|
for (unsigned j=0; j != LandingPads[i].BeginLabels.size(); ) {
|
2007-05-11 06:34:59 +08:00
|
|
|
unsigned BeginLabel = MappedLabel(LandingPad.BeginLabels[j]);
|
|
|
|
unsigned EndLabel = MappedLabel(LandingPad.EndLabels[j]);
|
Fix PR1628. When exception handling is turned on,
labels are generated bracketing each call (not just
invokes). This is used to generate entries in
the exception table required by the C++ personality.
However it gets in the way of tail-merging. This
patch solves the problem by no longer placing labels
around ordinary calls. Instead we generate entries
in the exception table that cover every instruction
in the function that wasn't covered by an invoke
range (the range given by the labels around the invoke).
As an optimization, such entries are only generated for
parts of the function that contain a call, since for
the moment those are the only instructions that can
throw an exception [1]. As a happy consequence, we
now get a smaller exception table, since the same
region can cover many calls. While there, I also
implemented folding of invoke ranges - successive
ranges are merged when safe to do so. Finally, if
a selector contains only a cleanup, there's a special
shorthand for it - place a 0 in the call-site entry.
I implemented this while there. As a result, the
exception table output (excluding filters) is now
optimal - it cannot be made smaller [2]. The
problem with throw filters is that folding them
optimally is hard, and the benefit of folding them is
minimal.
[1] I tested that having trapping instructions (eg
divide by zero) in such a region doesn't cause trouble.
[2] It could be made smaller with the help of higher
layers, eg by having branch folding reorder basic blocks
ending in invokes with the same landing pad so they
follow each other. I don't know if this is worth doing.
llvm-svn: 41718
2007-09-05 19:27:52 +08:00
|
|
|
|
2007-05-11 06:34:59 +08:00
|
|
|
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;
|
|
|
|
}
|
Fix PR1628. When exception handling is turned on,
labels are generated bracketing each call (not just
invokes). This is used to generate entries in
the exception table required by the C++ personality.
However it gets in the way of tail-merging. This
patch solves the problem by no longer placing labels
around ordinary calls. Instead we generate entries
in the exception table that cover every instruction
in the function that wasn't covered by an invoke
range (the range given by the labels around the invoke).
As an optimization, such entries are only generated for
parts of the function that contain a call, since for
the moment those are the only instructions that can
throw an exception [1]. As a happy consequence, we
now get a smaller exception table, since the same
region can cover many calls. While there, I also
implemented folding of invoke ranges - successive
ranges are merged when safe to do so. Finally, if
a selector contains only a cleanup, there's a special
shorthand for it - place a 0 in the call-site entry.
I implemented this while there. As a result, the
exception table output (excluding filters) is now
optimal - it cannot be made smaller [2]. The
problem with throw filters is that folding them
optimally is hard, and the benefit of folding them is
minimal.
[1] I tested that having trapping instructions (eg
divide by zero) in such a region doesn't cause trouble.
[2] It could be made smaller with the help of higher
layers, eg by having branch folding reorder basic blocks
ending in invokes with the same landing pad so they
follow each other. I don't know if this is worth doing.
llvm-svn: 41718
2007-09-05 19:27:52 +08:00
|
|
|
|
|
|
|
// Remove landing pads with no try-ranges.
|
2008-01-29 21:02:09 +08:00
|
|
|
if (LandingPads[i].BeginLabels.empty()) {
|
Fix PR1628. When exception handling is turned on,
labels are generated bracketing each call (not just
invokes). This is used to generate entries in
the exception table required by the C++ personality.
However it gets in the way of tail-merging. This
patch solves the problem by no longer placing labels
around ordinary calls. Instead we generate entries
in the exception table that cover every instruction
in the function that wasn't covered by an invoke
range (the range given by the labels around the invoke).
As an optimization, such entries are only generated for
parts of the function that contain a call, since for
the moment those are the only instructions that can
throw an exception [1]. As a happy consequence, we
now get a smaller exception table, since the same
region can cover many calls. While there, I also
implemented folding of invoke ranges - successive
ranges are merged when safe to do so. Finally, if
a selector contains only a cleanup, there's a special
shorthand for it - place a 0 in the call-site entry.
I implemented this while there. As a result, the
exception table output (excluding filters) is now
optimal - it cannot be made smaller [2]. The
problem with throw filters is that folding them
optimally is hard, and the benefit of folding them is
minimal.
[1] I tested that having trapping instructions (eg
divide by zero) in such a region doesn't cause trouble.
[2] It could be made smaller with the help of higher
layers, eg by having branch folding reorder basic blocks
ending in invokes with the same landing pad so they
follow each other. I don't know if this is worth doing.
llvm-svn: 41718
2007-09-05 19:27:52 +08:00
|
|
|
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();
|
|
|
|
|
2007-02-22 06:38:31 +08:00
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-27 05:27:09 +08:00
|
|
|
/// getTypeIDFor - Return the type id for the specified typeinfo. This is
|
2007-02-22 06:38:31 +08:00
|
|
|
/// function wide.
|
|
|
|
unsigned MachineModuleInfo::getTypeIDFor(GlobalVariable *TI) {
|
2008-07-04 06:53:42 +08:00
|
|
|
for (unsigned i = 0, N = TypeInfos.size(); i != N; ++i)
|
|
|
|
if (TypeInfos[i] == TI) return i + 1;
|
2007-02-22 06:38:31 +08:00
|
|
|
|
|
|
|
TypeInfos.push_back(TI);
|
|
|
|
return TypeInfos.size();
|
|
|
|
}
|
|
|
|
|
2007-06-03 00:53:42 +08:00
|
|
|
/// getFilterIDFor - Return the filter id for the specified typeinfos. This is
|
|
|
|
/// function wide.
|
2008-06-27 09:27:56 +08:00
|
|
|
int MachineModuleInfo::getFilterIDFor(std::vector<unsigned> &TyIds) {
|
2007-07-05 23:15:01 +08:00
|
|
|
// 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) {
|
2008-06-27 09:27:56 +08:00
|
|
|
unsigned i = *I, j = TyIds.size();
|
2007-07-05 23:15:01 +08:00
|
|
|
|
|
|
|
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);
|
2008-06-27 09:27:56 +08:00
|
|
|
|
2007-07-05 23:15:01 +08:00
|
|
|
try_next:;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add the new filter.
|
2008-06-27 09:27:56 +08:00
|
|
|
int FilterID = -(1 + FilterIds.size());
|
|
|
|
FilterIds.reserve(FilterIds.size() + TyIds.size() + 1);
|
|
|
|
for (unsigned I = 0, N = TyIds.size(); I != N; ++I)
|
2007-06-03 00:53:42 +08:00
|
|
|
FilterIds.push_back(TyIds[I]);
|
2008-06-27 09:27:56 +08:00
|
|
|
FilterEnds.push_back(FilterIds.size());
|
2007-06-03 00:53:42 +08:00
|
|
|
FilterIds.push_back(0); // terminator
|
|
|
|
return FilterID;
|
|
|
|
}
|
|
|
|
|
2007-05-13 23:42:26 +08:00
|
|
|
/// getPersonality - Return the personality function for the current function.
|
2007-02-22 06:38:31 +08:00
|
|
|
Function *MachineModuleInfo::getPersonality() const {
|
2007-05-13 06:36:25 +08:00
|
|
|
// FIXME: Until PR1414 will be fixed, we're using 1 personality function per
|
2007-05-13 23:42:26 +08:00
|
|
|
// function
|
|
|
|
return !LandingPads.empty() ? LandingPads[0].Personality : NULL;
|
2007-02-22 06:38:31 +08:00
|
|
|
}
|
|
|
|
|
2007-05-13 23:42:26 +08:00
|
|
|
/// getPersonalityIndex - Return unique index for current personality
|
2009-08-27 05:44:57 +08:00
|
|
|
/// function. NULL/first personality function should always get zero index.
|
2007-05-13 23:42:26 +08:00
|
|
|
unsigned MachineModuleInfo::getPersonalityIndex() const {
|
2007-05-23 19:08:31 +08:00
|
|
|
const Function* Personality = NULL;
|
2009-08-27 05:27:09 +08:00
|
|
|
|
2007-05-23 19:08:31 +08:00
|
|
|
// Scan landing pads. If there is at least one non-NULL personality - use it.
|
2008-07-04 06:53:42 +08:00
|
|
|
for (unsigned i = 0; i != LandingPads.size(); ++i)
|
2007-05-23 19:08:31 +08:00
|
|
|
if (LandingPads[i].Personality) {
|
|
|
|
Personality = LandingPads[i].Personality;
|
|
|
|
break;
|
|
|
|
}
|
2009-08-27 05:27:09 +08:00
|
|
|
|
2008-07-04 06:53:42 +08:00
|
|
|
for (unsigned i = 0; i < Personalities.size(); ++i) {
|
2007-05-13 23:42:26 +08:00
|
|
|
if (Personalities[i] == Personality)
|
|
|
|
return i;
|
2008-07-04 06:53:42 +08:00
|
|
|
}
|
2007-05-13 23:42:26 +08:00
|
|
|
|
2009-08-27 05:44:57 +08:00
|
|
|
// This will happen if the current personality function is
|
|
|
|
// in the zero index.
|
2007-05-13 23:42:26 +08:00
|
|
|
return 0;
|
|
|
|
}
|
2007-02-22 06:38:31 +08:00
|
|
|
|