forked from OSchip/llvm-project
Do not mark EH tables no-dead-strip unless the
associated function is so marked. llvm-svn: 46088
This commit is contained in:
parent
88d5909bed
commit
ed20366706
|
@ -35,6 +35,7 @@
|
||||||
#include "llvm/Support/DataTypes.h"
|
#include "llvm/Support/DataTypes.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/UniqueVector.h"
|
#include "llvm/ADT/UniqueVector.h"
|
||||||
|
#include "llvm/ADT/SmallPtrSet.h"
|
||||||
#include "llvm/GlobalValue.h"
|
#include "llvm/GlobalValue.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
|
|
||||||
|
@ -1037,6 +1038,10 @@ private:
|
||||||
// common EH frames.
|
// common EH frames.
|
||||||
std::vector<Function *> Personalities;
|
std::vector<Function *> Personalities;
|
||||||
|
|
||||||
|
// UsedFunctions - the functions in the llvm.used list in a more easily
|
||||||
|
// searchable format.
|
||||||
|
SmallPtrSet<const Function *, 32> UsedFunctions;
|
||||||
|
|
||||||
bool CallsEHReturn;
|
bool CallsEHReturn;
|
||||||
bool CallsUnwindInit;
|
bool CallsUnwindInit;
|
||||||
public:
|
public:
|
||||||
|
@ -1235,6 +1240,11 @@ public:
|
||||||
return Personalities;
|
return Personalities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UsedFunctions - Return set of the functions in the llvm.used list.
|
||||||
|
const SmallPtrSet<const Function *, 32>& getUsedFunctions() const {
|
||||||
|
return UsedFunctions;
|
||||||
|
}
|
||||||
|
|
||||||
/// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
|
/// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
|
||||||
///
|
///
|
||||||
void addCatchTypeInfo(MachineBasicBlock *LandingPad,
|
void addCatchTypeInfo(MachineBasicBlock *LandingPad,
|
||||||
|
|
|
@ -2764,15 +2764,14 @@ private:
|
||||||
bool hasCalls;
|
bool hasCalls;
|
||||||
bool hasLandingPads;
|
bool hasLandingPads;
|
||||||
std::vector<MachineMove> Moves;
|
std::vector<MachineMove> Moves;
|
||||||
Function::LinkageTypes linkage;
|
const Function * function;
|
||||||
|
|
||||||
FunctionEHFrameInfo(const std::string &FN, unsigned Num, unsigned P,
|
FunctionEHFrameInfo(const std::string &FN, unsigned Num, unsigned P,
|
||||||
bool hC, bool hL,
|
bool hC, bool hL,
|
||||||
const std::vector<MachineMove> &M,
|
const std::vector<MachineMove> &M,
|
||||||
Function::LinkageTypes l):
|
const Function *f):
|
||||||
FnName(FN), Number(Num), PersonalityIndex(P),
|
FnName(FN), Number(Num), PersonalityIndex(P),
|
||||||
hasCalls(hC), hasLandingPads(hL), Moves(M),
|
hasCalls(hC), hasLandingPads(hL), Moves(M), function (f) { }
|
||||||
linkage(l) { }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<FunctionEHFrameInfo> EHFrames;
|
std::vector<FunctionEHFrameInfo> EHFrames;
|
||||||
|
@ -2869,19 +2868,21 @@ private:
|
||||||
/// EmitEHFrame - Emit function exception frame information.
|
/// EmitEHFrame - Emit function exception frame information.
|
||||||
///
|
///
|
||||||
void EmitEHFrame(const FunctionEHFrameInfo &EHFrameInfo) {
|
void EmitEHFrame(const FunctionEHFrameInfo &EHFrameInfo) {
|
||||||
|
Function::LinkageTypes linkage = EHFrameInfo.function->getLinkage();
|
||||||
|
|
||||||
Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection());
|
Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection());
|
||||||
|
|
||||||
// Externally visible entry into the functions eh frame info.
|
// Externally visible entry into the functions eh frame info.
|
||||||
// If the corresponding function is static, this should not be
|
// If the corresponding function is static, this should not be
|
||||||
// externally visible.
|
// externally visible.
|
||||||
if (EHFrameInfo.linkage != Function::InternalLinkage) {
|
if (linkage != Function::InternalLinkage) {
|
||||||
if (const char *GlobalEHDirective = TAI->getGlobalEHDirective())
|
if (const char *GlobalEHDirective = TAI->getGlobalEHDirective())
|
||||||
O << GlobalEHDirective << EHFrameInfo.FnName << "\n";
|
O << GlobalEHDirective << EHFrameInfo.FnName << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// If corresponding function is weak definition, this should be too.
|
// If corresponding function is weak definition, this should be too.
|
||||||
if ((EHFrameInfo.linkage == Function::WeakLinkage ||
|
if ((linkage == Function::WeakLinkage ||
|
||||||
EHFrameInfo.linkage == Function::LinkOnceLinkage) &&
|
linkage == Function::LinkOnceLinkage) &&
|
||||||
TAI->getWeakDefDirective())
|
TAI->getWeakDefDirective())
|
||||||
O << TAI->getWeakDefDirective() << EHFrameInfo.FnName << "\n";
|
O << TAI->getWeakDefDirective() << EHFrameInfo.FnName << "\n";
|
||||||
|
|
||||||
|
@ -2889,12 +2890,17 @@ private:
|
||||||
// omit the EH Frame, but some environments do not handle weak absolute
|
// omit the EH Frame, but some environments do not handle weak absolute
|
||||||
// symbols.
|
// symbols.
|
||||||
if (!EHFrameInfo.hasCalls &&
|
if (!EHFrameInfo.hasCalls &&
|
||||||
((EHFrameInfo.linkage != Function::WeakLinkage &&
|
((linkage != Function::WeakLinkage &&
|
||||||
EHFrameInfo.linkage != Function::LinkOnceLinkage) ||
|
linkage != Function::LinkOnceLinkage) ||
|
||||||
!TAI->getWeakDefDirective() ||
|
!TAI->getWeakDefDirective() ||
|
||||||
TAI->getSupportsWeakOmittedEHFrame()))
|
TAI->getSupportsWeakOmittedEHFrame()))
|
||||||
{
|
{
|
||||||
O << EHFrameInfo.FnName << " = 0\n";
|
O << EHFrameInfo.FnName << " = 0\n";
|
||||||
|
// This name has no connection to the function, so it might get
|
||||||
|
// dead-stripped when the function is not, erroneously. Prohibit
|
||||||
|
// dead-stripping unconditionally.
|
||||||
|
if (const char *UsedDirective = TAI->getUsedDirective())
|
||||||
|
O << UsedDirective << EHFrameInfo.FnName << "\n\n";
|
||||||
} else {
|
} else {
|
||||||
O << EHFrameInfo.FnName << ":\n";
|
O << EHFrameInfo.FnName << ":\n";
|
||||||
|
|
||||||
|
@ -2941,10 +2947,16 @@ private:
|
||||||
|
|
||||||
Asm->EmitAlignment(2);
|
Asm->EmitAlignment(2);
|
||||||
EmitLabel("eh_frame_end", EHFrameInfo.Number);
|
EmitLabel("eh_frame_end", EHFrameInfo.Number);
|
||||||
}
|
|
||||||
|
|
||||||
if (const char *UsedDirective = TAI->getUsedDirective())
|
// If the function is marked used, this table should be also. We cannot
|
||||||
O << UsedDirective << EHFrameInfo.FnName << "\n\n";
|
// make the mark unconditional in this case, since retaining the table
|
||||||
|
// also retains the function in this case, and there is code around
|
||||||
|
// that depends on unused functions (calling undefined externals) being
|
||||||
|
// dead-stripped to link correctly. Yes, there really is.
|
||||||
|
if (MMI->getUsedFunctions().count(EHFrameInfo.function))
|
||||||
|
if (const char *UsedDirective = TAI->getUsedDirective())
|
||||||
|
O << UsedDirective << EHFrameInfo.FnName << "\n\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EmitExceptionTable - Emit landing pads and actions.
|
/// EmitExceptionTable - Emit landing pads and actions.
|
||||||
|
@ -3414,7 +3426,7 @@ public:
|
||||||
MF->getFrameInfo()->hasCalls(),
|
MF->getFrameInfo()->hasCalls(),
|
||||||
!MMI->getLandingPads().empty(),
|
!MMI->getLandingPads().empty(),
|
||||||
MMI->getFrameMoves(),
|
MMI->getFrameMoves(),
|
||||||
MF->getFunction()->getLinkage()));
|
MF->getFunction()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1552,6 +1552,21 @@ bool MachineModuleInfo::Verify(Value *V) {
|
||||||
///
|
///
|
||||||
void MachineModuleInfo::AnalyzeModule(Module &M) {
|
void MachineModuleInfo::AnalyzeModule(Module &M) {
|
||||||
SetupCompileUnits(M);
|
SetupCompileUnits(M);
|
||||||
|
|
||||||
|
// Insert functions in the llvm.used array into UsedFunctions.
|
||||||
|
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;
|
||||||
|
|
||||||
|
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
|
||||||
|
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(InitList->getOperand(i)))
|
||||||
|
if (CE->getOpcode() == Instruction::BitCast)
|
||||||
|
if (Function *F = dyn_cast<Function>(CE->getOperand(0)))
|
||||||
|
UsedFunctions.insert(F);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// needsFrameInfo - Returns true if we need to gather callee-saved register
|
/// needsFrameInfo - Returns true if we need to gather callee-saved register
|
||||||
|
|
Loading…
Reference in New Issue