mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-28 06:00:30 +00:00
CodeGen: Remove pipeline dependencies on StackProtector; NFC
This re-applies r336929 with a fix to accomodate for the Mips target scheduling multiple SelectionDAG instances into the pass pipeline. PrologEpilogInserter and StackColoring depend on the StackProtector analysis being alive from the point it is run until PEI, which requires that they are all scheduled in the same FunctionPassManager. Inserting a (machine) ModulePass between StackProtector and PEI results in these passes being in separate FunctionPassManagers and the StackProtector is not available for PEI. PEI and StackColoring don't use much information from the StackProtector pass, so transfering the required information to MachineFrameInfo is cleaner than keeping the StackProtector pass around. This commit moves the SSP layout information to MFI instead of keeping it in the pass. This patch set (D37580, D37581, D37582, D37583, D37584, D37585, D37586, D37587) is a first draft of the pagerando implementation described in http://lists.llvm.org/pipermail/llvm-dev/2017-June/113794.html. Patch by Stephen Crane <sjc@immunant.com> Differential Revision: https://reviews.llvm.org/D49256 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@336964 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
674f0a1174
commit
d79789afc6
@ -70,6 +70,8 @@ public:
|
||||
.set(MachineFunctionProperties::Property::RegBankSelected);
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
|
||||
bool runOnMachineFunction(MachineFunction &MF) override;
|
||||
};
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class AnalysisUsage;
|
||||
class MachineFunction;
|
||||
class MachineInstr;
|
||||
class MachineOperand;
|
||||
@ -102,5 +103,10 @@ MachineInstr *getOpcodeDef(unsigned Opcode, unsigned Reg,
|
||||
|
||||
/// Returns an APFloat from Val converted to the appropriate size.
|
||||
APFloat getAPFloatFromSize(double Val, unsigned Size);
|
||||
|
||||
/// Modify analysis usage so it preserves passes required for the SelectionDAG
|
||||
/// fallback.
|
||||
void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU);
|
||||
|
||||
} // End namespace llvm.
|
||||
#endif
|
||||
|
@ -87,7 +87,21 @@ public:
|
||||
///
|
||||
/// Abstract Stack Frame Information
|
||||
class MachineFrameInfo {
|
||||
public:
|
||||
/// Stack Smashing Protection (SSP) rules require that vulnerable stack
|
||||
/// allocations are located close the stack protector.
|
||||
enum SSPLayoutKind {
|
||||
SSPLK_None, ///< Did not trigger a stack protector. No effect on data
|
||||
///< layout.
|
||||
SSPLK_LargeArray, ///< Array or nested array >= SSP-buffer-size. Closest
|
||||
///< to the stack protector.
|
||||
SSPLK_SmallArray, ///< Array or nested array < SSP-buffer-size. 2nd closest
|
||||
///< to the stack protector.
|
||||
SSPLK_AddrOf ///< The address of this allocation is exposed and
|
||||
///< triggered protection. 3rd closest to the protector.
|
||||
};
|
||||
|
||||
private:
|
||||
// Represent a single object allocated on the stack.
|
||||
struct StackObject {
|
||||
// The offset of this object from the stack pointer on entry to
|
||||
@ -148,12 +162,15 @@ class MachineFrameInfo {
|
||||
/// If true, the object has been zero-extended.
|
||||
bool isSExt = false;
|
||||
|
||||
uint8_t SSPLayout;
|
||||
|
||||
StackObject(uint64_t Size, unsigned Alignment, int64_t SPOffset,
|
||||
bool IsImmutable, bool IsSpillSlot, const AllocaInst *Alloca,
|
||||
bool IsAliased, uint8_t StackID = 0)
|
||||
: SPOffset(SPOffset), Size(Size), Alignment(Alignment),
|
||||
isImmutable(IsImmutable), isSpillSlot(IsSpillSlot),
|
||||
StackID(StackID), Alloca(Alloca), isAliased(IsAliased) {}
|
||||
StackID(StackID), Alloca(Alloca), isAliased(IsAliased),
|
||||
SSPLayout(SSPLK_None) {}
|
||||
};
|
||||
|
||||
/// The alignment of the stack.
|
||||
@ -488,6 +505,20 @@ public:
|
||||
Objects[ObjectIdx+NumFixedObjects].SPOffset = SPOffset;
|
||||
}
|
||||
|
||||
SSPLayoutKind getObjectSSPLayout(int ObjectIdx) const {
|
||||
assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
|
||||
"Invalid Object Idx!");
|
||||
return (SSPLayoutKind)Objects[ObjectIdx+NumFixedObjects].SSPLayout;
|
||||
}
|
||||
|
||||
void setObjectSSPLayout(int ObjectIdx, SSPLayoutKind Kind) {
|
||||
assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
|
||||
"Invalid Object Idx!");
|
||||
assert(!isDeadObjectIndex(ObjectIdx) &&
|
||||
"Setting SSP layout for a dead object?");
|
||||
Objects[ObjectIdx+NumFixedObjects].SSPLayout = Kind;
|
||||
}
|
||||
|
||||
/// Return the number of bytes that must be allocated to hold
|
||||
/// all of the fixed size frame objects. This is only valid after
|
||||
/// Prolog/Epilog code insertion has finalized the stack frame layout.
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/ValueMap.h"
|
||||
#include "llvm/Pass.h"
|
||||
@ -35,24 +36,11 @@ class TargetMachine;
|
||||
class Type;
|
||||
|
||||
class StackProtector : public FunctionPass {
|
||||
public:
|
||||
/// SSPLayoutKind. Stack Smashing Protection (SSP) rules require that
|
||||
/// vulnerable stack allocations are located close the stack protector.
|
||||
enum SSPLayoutKind {
|
||||
SSPLK_None, ///< Did not trigger a stack protector. No effect on data
|
||||
///< layout.
|
||||
SSPLK_LargeArray, ///< Array or nested array >= SSP-buffer-size. Closest
|
||||
///< to the stack protector.
|
||||
SSPLK_SmallArray, ///< Array or nested array < SSP-buffer-size. 2nd closest
|
||||
///< to the stack protector.
|
||||
SSPLK_AddrOf ///< The address of this allocation is exposed and
|
||||
///< triggered protection. 3rd closest to the protector.
|
||||
};
|
||||
|
||||
/// A mapping of AllocaInsts to their required SSP layout.
|
||||
using SSPLayoutMap = ValueMap<const AllocaInst *, SSPLayoutKind>;
|
||||
|
||||
private:
|
||||
/// A mapping of AllocaInsts to their required SSP layout.
|
||||
using SSPLayoutMap = DenseMap<const AllocaInst *,
|
||||
MachineFrameInfo::SSPLayoutKind>;
|
||||
|
||||
const TargetMachine *TM = nullptr;
|
||||
|
||||
/// TLI - Keep a pointer of a TargetLowering to consult for determining
|
||||
@ -123,14 +111,12 @@ public:
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
|
||||
SSPLayoutKind getSSPLayout(const AllocaInst *AI) const;
|
||||
|
||||
// Return true if StackProtector is supposed to be handled by SelectionDAG.
|
||||
bool shouldEmitSDCheck(const BasicBlock &BB) const;
|
||||
|
||||
void adjustForColoring(const AllocaInst *From, const AllocaInst *To);
|
||||
|
||||
bool runOnFunction(Function &Fn) override;
|
||||
|
||||
void copyToMachineFrameInfo(MachineFrameInfo &MFI) const;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "llvm/CodeGen/MachineMemOperand.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/StackProtector.h"
|
||||
#include "llvm/CodeGen/TargetFrameLowering.h"
|
||||
#include "llvm/CodeGen/TargetLowering.h"
|
||||
#include "llvm/CodeGen/TargetPassConfig.h"
|
||||
@ -102,7 +103,9 @@ IRTranslator::IRTranslator() : MachineFunctionPass(ID) {
|
||||
}
|
||||
|
||||
void IRTranslator::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<StackProtector>();
|
||||
AU.addRequired<TargetPassConfig>();
|
||||
getSelectionDAGFallbackAnalysisUsage(AU);
|
||||
MachineFunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
|
||||
@ -1650,5 +1653,9 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
|
||||
assert(&MF->front() == &NewEntryBB &&
|
||||
"New entry wasn't next in the list of basic block!");
|
||||
|
||||
// Initialize stack protector information.
|
||||
StackProtector &SP = getAnalysis<StackProtector>();
|
||||
SP.copyToMachineFrameInfo(MF->getFrameInfo());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ InstructionSelect::InstructionSelect() : MachineFunctionPass(ID) {
|
||||
|
||||
void InstructionSelect::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<TargetPassConfig>();
|
||||
getSelectionDAGFallbackAnalysisUsage(AU);
|
||||
MachineFunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@ Legalizer::Legalizer() : MachineFunctionPass(ID) {
|
||||
|
||||
void Legalizer::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<TargetPassConfig>();
|
||||
getSelectionDAGFallbackAnalysisUsage(AU);
|
||||
MachineFunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,11 @@ bool Localizer::shouldLocalize(const MachineInstr &MI) {
|
||||
}
|
||||
}
|
||||
|
||||
void Localizer::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
getSelectionDAGFallbackAnalysisUsage(AU);
|
||||
MachineFunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
|
||||
bool Localizer::isLocalUse(MachineOperand &MOUse, const MachineInstr &Def,
|
||||
MachineBasicBlock *&InsertMBB) {
|
||||
MachineInstr &MIUse = *MOUse.getParent();
|
||||
|
@ -105,6 +105,7 @@ void RegBankSelect::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<MachineBranchProbabilityInfo>();
|
||||
}
|
||||
AU.addRequired<TargetPassConfig>();
|
||||
getSelectionDAGFallbackAnalysisUsage(AU);
|
||||
MachineFunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/StackProtector.h"
|
||||
#include "llvm/CodeGen/TargetInstrInfo.h"
|
||||
#include "llvm/CodeGen/TargetPassConfig.h"
|
||||
#include "llvm/CodeGen/TargetRegisterInfo.h"
|
||||
@ -233,3 +234,7 @@ APFloat llvm::getAPFloatFromSize(double Val, unsigned Size) {
|
||||
APF.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
|
||||
return APF;
|
||||
}
|
||||
|
||||
void llvm::getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU) {
|
||||
AU.addPreserved<StackProtector>();
|
||||
}
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/StackProtector.h"
|
||||
#include "llvm/CodeGen/TargetFrameLowering.h"
|
||||
#include "llvm/CodeGen/TargetOpcodes.h"
|
||||
#include "llvm/CodeGen/TargetRegisterInfo.h"
|
||||
@ -99,7 +98,6 @@ namespace {
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.setPreservesCFG();
|
||||
AU.addRequired<StackProtector>();
|
||||
MachineFunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
};
|
||||
@ -109,11 +107,7 @@ namespace {
|
||||
char LocalStackSlotPass::ID = 0;
|
||||
|
||||
char &llvm::LocalStackSlotAllocationID = LocalStackSlotPass::ID;
|
||||
|
||||
INITIALIZE_PASS_BEGIN(LocalStackSlotPass, DEBUG_TYPE,
|
||||
"Local Stack Slot Allocation", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(StackProtector)
|
||||
INITIALIZE_PASS_END(LocalStackSlotPass, DEBUG_TYPE,
|
||||
INITIALIZE_PASS(LocalStackSlotPass, DEBUG_TYPE,
|
||||
"Local Stack Slot Allocation", false, false)
|
||||
|
||||
bool LocalStackSlotPass::runOnMachineFunction(MachineFunction &MF) {
|
||||
@ -202,7 +196,6 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
|
||||
TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
|
||||
int64_t Offset = 0;
|
||||
unsigned MaxAlign = 0;
|
||||
StackProtector *SP = &getAnalysis<StackProtector>();
|
||||
|
||||
// Make sure that the stack protector comes before the local variables on the
|
||||
// stack.
|
||||
@ -222,16 +215,16 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
|
||||
if (MFI.getStackProtectorIndex() == (int)i)
|
||||
continue;
|
||||
|
||||
switch (SP->getSSPLayout(MFI.getObjectAllocation(i))) {
|
||||
case StackProtector::SSPLK_None:
|
||||
switch (MFI.getObjectSSPLayout(i)) {
|
||||
case MachineFrameInfo::SSPLK_None:
|
||||
continue;
|
||||
case StackProtector::SSPLK_SmallArray:
|
||||
case MachineFrameInfo::SSPLK_SmallArray:
|
||||
SmallArrayObjs.insert(i);
|
||||
continue;
|
||||
case StackProtector::SSPLK_AddrOf:
|
||||
case MachineFrameInfo::SSPLK_AddrOf:
|
||||
AddrOfObjs.insert(i);
|
||||
continue;
|
||||
case StackProtector::SSPLK_LargeArray:
|
||||
case MachineFrameInfo::SSPLK_LargeArray:
|
||||
LargeArrayObjs.insert(i);
|
||||
continue;
|
||||
}
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/CodeGen/StackProtector.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
|
||||
@ -85,7 +84,6 @@ void MachineFunctionPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addPreserved<MemoryDependenceWrapperPass>();
|
||||
AU.addPreserved<ScalarEvolutionWrapperPass>();
|
||||
AU.addPreserved<SCEVAAWrapperPass>();
|
||||
AU.addPreserved<StackProtector>();
|
||||
|
||||
FunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/RegisterScavenging.h"
|
||||
#include "llvm/CodeGen/StackProtector.h"
|
||||
#include "llvm/CodeGen/TargetFrameLowering.h"
|
||||
#include "llvm/CodeGen/TargetInstrInfo.h"
|
||||
#include "llvm/CodeGen/TargetOpcodes.h"
|
||||
@ -143,7 +142,6 @@ INITIALIZE_PASS_BEGIN(PEI, DEBUG_TYPE, "Prologue/Epilogue Insertion", false,
|
||||
false)
|
||||
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
|
||||
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
|
||||
INITIALIZE_PASS_DEPENDENCY(StackProtector)
|
||||
INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass)
|
||||
INITIALIZE_PASS_END(PEI, DEBUG_TYPE,
|
||||
"Prologue/Epilogue Insertion & Frame Finalization", false,
|
||||
@ -160,7 +158,6 @@ void PEI::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesCFG();
|
||||
AU.addPreserved<MachineLoopInfo>();
|
||||
AU.addPreserved<MachineDominatorTree>();
|
||||
AU.addRequired<StackProtector>();
|
||||
AU.addRequired<MachineOptimizationRemarkEmitterPass>();
|
||||
MachineFunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
@ -695,7 +692,6 @@ AssignProtectedObjSet(const StackObjSet &UnassignedObjs,
|
||||
/// abstract stack objects.
|
||||
void PEI::calculateFrameObjectOffsets(MachineFunction &MF) {
|
||||
const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
|
||||
StackProtector *SP = &getAnalysis<StackProtector>();
|
||||
|
||||
bool StackGrowsDown =
|
||||
TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
|
||||
@ -844,16 +840,16 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &MF) {
|
||||
EHRegNodeFrameIndex == (int)i)
|
||||
continue;
|
||||
|
||||
switch (SP->getSSPLayout(MFI.getObjectAllocation(i))) {
|
||||
case StackProtector::SSPLK_None:
|
||||
switch (MFI.getObjectSSPLayout(i)) {
|
||||
case MachineFrameInfo::SSPLK_None:
|
||||
continue;
|
||||
case StackProtector::SSPLK_SmallArray:
|
||||
case MachineFrameInfo::SSPLK_SmallArray:
|
||||
SmallArrayObjs.insert(i);
|
||||
continue;
|
||||
case StackProtector::SSPLK_AddrOf:
|
||||
case MachineFrameInfo::SSPLK_AddrOf:
|
||||
AddrOfObjs.insert(i);
|
||||
continue;
|
||||
case StackProtector::SSPLK_LargeArray:
|
||||
case MachineFrameInfo::SSPLK_LargeArray:
|
||||
LargeArrayObjs.insert(i);
|
||||
continue;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/StackProtector.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/IR/DiagnosticInfo.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
@ -44,6 +45,11 @@ namespace {
|
||||
|
||||
StringRef getPassName() const override { return "ResetMachineFunction"; }
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addPreserved<StackProtector>();
|
||||
MachineFunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
|
||||
bool runOnMachineFunction(MachineFunction &MF) override {
|
||||
// No matter what happened, whether we successfully selected the function
|
||||
// or not, nothing is going to use the vreg types after us. Make sure they
|
||||
|
@ -328,7 +328,6 @@ void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<AAResultsWrapperPass>();
|
||||
AU.addRequired<GCModuleInfo>();
|
||||
AU.addRequired<StackProtector>();
|
||||
AU.addPreserved<StackProtector>();
|
||||
AU.addPreserved<GCModuleInfo>();
|
||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||
AU.addRequired<TargetTransformInfoWrapperPass>();
|
||||
@ -1544,6 +1543,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
|
||||
processDbgDeclares(FuncInfo);
|
||||
|
||||
// Iterate over all basic blocks in the function.
|
||||
StackProtector &SP = getAnalysis<StackProtector>();
|
||||
for (const BasicBlock *LLVMBB : RPOT) {
|
||||
if (OptLevel != CodeGenOpt::None) {
|
||||
bool AllPredsVisited = true;
|
||||
@ -1713,7 +1713,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
|
||||
FastIS->recomputeInsertPt();
|
||||
}
|
||||
|
||||
if (getAnalysis<StackProtector>().shouldEmitSDCheck(*LLVMBB)) {
|
||||
if (SP.shouldEmitSDCheck(*LLVMBB)) {
|
||||
bool FunctionBasedInstrumentation =
|
||||
TLI->getSSPStackGuardCheck(*Fn.getParent());
|
||||
SDB->SPDescriptor.initialize(LLVMBB, FuncInfo->MBBMap[LLVMBB],
|
||||
@ -1746,6 +1746,8 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
|
||||
ElidedArgCopyInstrs.clear();
|
||||
}
|
||||
|
||||
SP.copyToMachineFrameInfo(MF->getFrameInfo());
|
||||
|
||||
propagateSwiftErrorVRegs(FuncInfo);
|
||||
|
||||
delete FastIS;
|
||||
|
@ -39,7 +39,6 @@
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/CodeGen/SelectionDAGNodes.h"
|
||||
#include "llvm/CodeGen/SlotIndexes.h"
|
||||
#include "llvm/CodeGen/StackProtector.h"
|
||||
#include "llvm/CodeGen/TargetOpcodes.h"
|
||||
#include "llvm/CodeGen/WinEHFuncInfo.h"
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
@ -423,9 +422,6 @@ class StackColoring : public MachineFunctionPass {
|
||||
/// SlotIndex analysis object.
|
||||
SlotIndexes *Indexes;
|
||||
|
||||
/// The stack protector object.
|
||||
StackProtector *SP;
|
||||
|
||||
/// The list of lifetime markers found. These markers are to be removed
|
||||
/// once the coloring is done.
|
||||
SmallVector<MachineInstr*, 8> Markers;
|
||||
@ -524,13 +520,11 @@ char &llvm::StackColoringID = StackColoring::ID;
|
||||
INITIALIZE_PASS_BEGIN(StackColoring, DEBUG_TYPE,
|
||||
"Merge disjoint stack slots", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
|
||||
INITIALIZE_PASS_DEPENDENCY(StackProtector)
|
||||
INITIALIZE_PASS_END(StackColoring, DEBUG_TYPE,
|
||||
"Merge disjoint stack slots", false, false)
|
||||
|
||||
void StackColoring::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<SlotIndexes>();
|
||||
AU.addRequired<StackProtector>();
|
||||
MachineFunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
|
||||
@ -936,9 +930,17 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
|
||||
MergedAllocas.insert(From);
|
||||
MergedAllocas.insert(To);
|
||||
|
||||
// Allow the stack protector to adjust its value map to account for the
|
||||
// upcoming replacement.
|
||||
SP->adjustForColoring(From, To);
|
||||
// Transfer the stack protector layout tag, but make sure that SSPLK_AddrOf
|
||||
// does not overwrite SSPLK_SmallArray or SSPLK_LargeArray, and make sure
|
||||
// that SSPLK_SmallArray does not overwrite SSPLK_LargeArray.
|
||||
MachineFrameInfo::SSPLayoutKind FromKind
|
||||
= MFI->getObjectSSPLayout(SI.first);
|
||||
MachineFrameInfo::SSPLayoutKind ToKind = MFI->getObjectSSPLayout(SI.second);
|
||||
if (FromKind != MachineFrameInfo::SSPLK_None &&
|
||||
(ToKind == MachineFrameInfo::SSPLK_None ||
|
||||
(ToKind != MachineFrameInfo::SSPLK_LargeArray &&
|
||||
FromKind != MachineFrameInfo::SSPLK_AddrOf)))
|
||||
MFI->setObjectSSPLayout(SI.second, FromKind);
|
||||
|
||||
// The new alloca might not be valid in a llvm.dbg.declare for this
|
||||
// variable, so undef out the use to make the verifier happy.
|
||||
@ -1139,7 +1141,6 @@ bool StackColoring::runOnMachineFunction(MachineFunction &Func) {
|
||||
MF = &Func;
|
||||
MFI = &MF->getFrameInfo();
|
||||
Indexes = &getAnalysis<SlotIndexes>();
|
||||
SP = &getAnalysis<StackProtector>();
|
||||
BlockLiveness.clear();
|
||||
BasicBlocks.clear();
|
||||
BasicBlockNumbering.clear();
|
||||
|
@ -70,32 +70,6 @@ INITIALIZE_PASS_END(StackProtector, DEBUG_TYPE,
|
||||
|
||||
FunctionPass *llvm::createStackProtectorPass() { return new StackProtector(); }
|
||||
|
||||
StackProtector::SSPLayoutKind
|
||||
StackProtector::getSSPLayout(const AllocaInst *AI) const {
|
||||
return AI ? Layout.lookup(AI) : SSPLK_None;
|
||||
}
|
||||
|
||||
void StackProtector::adjustForColoring(const AllocaInst *From,
|
||||
const AllocaInst *To) {
|
||||
// When coloring replaces one alloca with another, transfer the SSPLayoutKind
|
||||
// tag from the remapped to the target alloca. The remapped alloca should
|
||||
// have a size smaller than or equal to the replacement alloca.
|
||||
SSPLayoutMap::iterator I = Layout.find(From);
|
||||
if (I != Layout.end()) {
|
||||
SSPLayoutKind Kind = I->second;
|
||||
Layout.erase(I);
|
||||
|
||||
// Transfer the tag, but make sure that SSPLK_AddrOf does not overwrite
|
||||
// SSPLK_SmallArray or SSPLK_LargeArray, and make sure that
|
||||
// SSPLK_SmallArray does not overwrite SSPLK_LargeArray.
|
||||
I = Layout.find(To);
|
||||
if (I == Layout.end())
|
||||
Layout.insert(std::make_pair(To, Kind));
|
||||
else if (I->second != SSPLK_LargeArray && Kind != SSPLK_AddrOf)
|
||||
I->second = Kind;
|
||||
}
|
||||
}
|
||||
|
||||
void StackProtector::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<TargetPassConfig>();
|
||||
AU.addPreserved<DominatorTreeWrapperPass>();
|
||||
@ -289,18 +263,21 @@ bool StackProtector::RequiresStackProtector() {
|
||||
if (CI->getLimitedValue(SSPBufferSize) >= SSPBufferSize) {
|
||||
// A call to alloca with size >= SSPBufferSize requires
|
||||
// stack protectors.
|
||||
Layout.insert(std::make_pair(AI, SSPLK_LargeArray));
|
||||
Layout.insert(std::make_pair(AI,
|
||||
MachineFrameInfo::SSPLK_LargeArray));
|
||||
ORE.emit(RemarkBuilder);
|
||||
NeedsProtector = true;
|
||||
} else if (Strong) {
|
||||
// Require protectors for all alloca calls in strong mode.
|
||||
Layout.insert(std::make_pair(AI, SSPLK_SmallArray));
|
||||
Layout.insert(std::make_pair(AI,
|
||||
MachineFrameInfo::SSPLK_SmallArray));
|
||||
ORE.emit(RemarkBuilder);
|
||||
NeedsProtector = true;
|
||||
}
|
||||
} else {
|
||||
// A call to alloca with a variable size requires protectors.
|
||||
Layout.insert(std::make_pair(AI, SSPLK_LargeArray));
|
||||
Layout.insert(std::make_pair(AI,
|
||||
MachineFrameInfo::SSPLK_LargeArray));
|
||||
ORE.emit(RemarkBuilder);
|
||||
NeedsProtector = true;
|
||||
}
|
||||
@ -309,8 +286,9 @@ bool StackProtector::RequiresStackProtector() {
|
||||
|
||||
bool IsLarge = false;
|
||||
if (ContainsProtectableArray(AI->getAllocatedType(), IsLarge, Strong)) {
|
||||
Layout.insert(std::make_pair(AI, IsLarge ? SSPLK_LargeArray
|
||||
: SSPLK_SmallArray));
|
||||
Layout.insert(std::make_pair(AI, IsLarge
|
||||
? MachineFrameInfo::SSPLK_LargeArray
|
||||
: MachineFrameInfo::SSPLK_SmallArray));
|
||||
ORE.emit([&]() {
|
||||
return OptimizationRemark(DEBUG_TYPE, "StackProtectorBuffer", &I)
|
||||
<< "Stack protection applied to function "
|
||||
@ -324,7 +302,7 @@ bool StackProtector::RequiresStackProtector() {
|
||||
|
||||
if (Strong && HasAddressTaken(AI)) {
|
||||
++NumAddrTaken;
|
||||
Layout.insert(std::make_pair(AI, SSPLK_AddrOf));
|
||||
Layout.insert(std::make_pair(AI, MachineFrameInfo::SSPLK_AddrOf));
|
||||
ORE.emit([&]() {
|
||||
return OptimizationRemark(DEBUG_TYPE, "StackProtectorAddressTaken",
|
||||
&I)
|
||||
@ -534,3 +512,23 @@ BasicBlock *StackProtector::CreateFailBB() {
|
||||
bool StackProtector::shouldEmitSDCheck(const BasicBlock &BB) const {
|
||||
return HasPrologue && !HasIRCheck && dyn_cast<ReturnInst>(BB.getTerminator());
|
||||
}
|
||||
|
||||
void StackProtector::copyToMachineFrameInfo(MachineFrameInfo &MFI) const {
|
||||
if (Layout.empty())
|
||||
return;
|
||||
|
||||
for (int I = 0, E = MFI.getObjectIndexEnd(); I != E; ++I) {
|
||||
if (MFI.isDeadObjectIndex(I))
|
||||
continue;
|
||||
|
||||
const AllocaInst *AI = MFI.getObjectAllocation(I);
|
||||
if (!AI)
|
||||
continue;
|
||||
|
||||
SSPLayoutMap::const_iterator LI = Layout.find(AI);
|
||||
if (LI == Layout.end())
|
||||
continue;
|
||||
|
||||
MFI.setObjectSSPLayout(I, LI->second);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/SelectionDAGNodes.h"
|
||||
#include "llvm/CodeGen/StackProtector.h"
|
||||
#include "llvm/IR/CFG.h"
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
@ -46,6 +47,13 @@ using namespace llvm;
|
||||
// instructions for SelectionDAG operations.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void MipsDAGToDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
// There are multiple MipsDAGToDAGISel instances added to the pass pipeline.
|
||||
// We need to preserve StackProtector for the next one.
|
||||
AU.addPreserved<StackProtector>();
|
||||
SelectionDAGISel::getAnalysisUsage(AU);
|
||||
}
|
||||
|
||||
bool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
|
||||
Subtarget = &static_cast<const MipsSubtarget &>(MF.getSubtarget());
|
||||
bool Ret = SelectionDAGISel::runOnMachineFunction(MF);
|
||||
|
@ -41,6 +41,8 @@ public:
|
||||
|
||||
bool runOnMachineFunction(MachineFunction &MF) override;
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
|
||||
protected:
|
||||
SDNode *getGlobalBaseReg();
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "Mips.h"
|
||||
#include "MipsTargetMachine.h"
|
||||
#include "llvm/CodeGen/TargetPassConfig.h"
|
||||
#include "llvm/CodeGen/StackProtector.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
@ -32,6 +33,7 @@ namespace {
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.addRequired<TargetPassConfig>();
|
||||
AU.addPreserved<StackProtector>();
|
||||
MachineFunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user