Просмотр исходного кода

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
Matthias Braun 7 лет назад
Родитель
Сommit
d79789afc6

+ 2 - 0
include/llvm/CodeGen/GlobalISel/Localizer.h

@@ -70,6 +70,8 @@ public:
         .set(MachineFunctionProperties::Property::RegBankSelected);
         .set(MachineFunctionProperties::Property::RegBankSelected);
   }
   }
 
 
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+
   bool runOnMachineFunction(MachineFunction &MF) override;
   bool runOnMachineFunction(MachineFunction &MF) override;
 };
 };
 
 

+ 6 - 0
include/llvm/CodeGen/GlobalISel/Utils.h

@@ -19,6 +19,7 @@
 
 
 namespace llvm {
 namespace llvm {
 
 
+class AnalysisUsage;
 class MachineFunction;
 class MachineFunction;
 class MachineInstr;
 class MachineInstr;
 class MachineOperand;
 class MachineOperand;
@@ -102,5 +103,10 @@ MachineInstr *getOpcodeDef(unsigned Opcode, unsigned Reg,
 
 
 /// Returns an APFloat from Val converted to the appropriate size.
 /// Returns an APFloat from Val converted to the appropriate size.
 APFloat getAPFloatFromSize(double Val, unsigned 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.
 } // End namespace llvm.
 #endif
 #endif

+ 32 - 1
include/llvm/CodeGen/MachineFrameInfo.h

@@ -87,7 +87,21 @@ public:
 ///
 ///
 /// Abstract Stack Frame Information
 /// Abstract Stack Frame Information
 class MachineFrameInfo {
 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.
   // Represent a single object allocated on the stack.
   struct StackObject {
   struct StackObject {
     // The offset of this object from the stack pointer on entry to
     // 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.
     /// If true, the object has been zero-extended.
     bool isSExt = false;
     bool isSExt = false;
 
 
+    uint8_t SSPLayout;
+
     StackObject(uint64_t Size, unsigned Alignment, int64_t SPOffset,
     StackObject(uint64_t Size, unsigned Alignment, int64_t SPOffset,
                 bool IsImmutable, bool IsSpillSlot, const AllocaInst *Alloca,
                 bool IsImmutable, bool IsSpillSlot, const AllocaInst *Alloca,
                 bool IsAliased, uint8_t StackID = 0)
                 bool IsAliased, uint8_t StackID = 0)
       : SPOffset(SPOffset), Size(Size), Alignment(Alignment),
       : SPOffset(SPOffset), Size(Size), Alignment(Alignment),
         isImmutable(IsImmutable), isSpillSlot(IsSpillSlot),
         isImmutable(IsImmutable), isSpillSlot(IsSpillSlot),
-        StackID(StackID), Alloca(Alloca), isAliased(IsAliased) {}
+        StackID(StackID), Alloca(Alloca), isAliased(IsAliased),
+        SSPLayout(SSPLK_None) {}
   };
   };
 
 
   /// The alignment of the stack.
   /// The alignment of the stack.
@@ -488,6 +505,20 @@ public:
     Objects[ObjectIdx+NumFixedObjects].SPOffset = SPOffset;
     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
   /// Return the number of bytes that must be allocated to hold
   /// all of the fixed size frame objects.  This is only valid after
   /// all of the fixed size frame objects.  This is only valid after
   /// Prolog/Epilog code insertion has finalized the stack frame layout.
   /// Prolog/Epilog code insertion has finalized the stack frame layout.

+ 6 - 20
include/llvm/CodeGen/StackProtector.h

@@ -19,6 +19,7 @@
 
 
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/ADT/Triple.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/ValueMap.h"
 #include "llvm/IR/ValueMap.h"
 #include "llvm/Pass.h"
 #include "llvm/Pass.h"
@@ -35,24 +36,11 @@ class TargetMachine;
 class Type;
 class Type;
 
 
 class StackProtector : public FunctionPass {
 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.
-  };
-
+private:
   /// A mapping of AllocaInsts to their required SSP layout.
   /// A mapping of AllocaInsts to their required SSP layout.
-  using SSPLayoutMap = ValueMap<const AllocaInst *, SSPLayoutKind>;
+  using SSPLayoutMap = DenseMap<const AllocaInst *,
+                                MachineFrameInfo::SSPLayoutKind>;
 
 
-private:
   const TargetMachine *TM = nullptr;
   const TargetMachine *TM = nullptr;
 
 
   /// TLI - Keep a pointer of a TargetLowering to consult for determining
   /// TLI - Keep a pointer of a TargetLowering to consult for determining
@@ -123,14 +111,12 @@ public:
 
 
   void getAnalysisUsage(AnalysisUsage &AU) const override;
   void getAnalysisUsage(AnalysisUsage &AU) const override;
 
 
-  SSPLayoutKind getSSPLayout(const AllocaInst *AI) const;
-
   // Return true if StackProtector is supposed to be handled by SelectionDAG.
   // Return true if StackProtector is supposed to be handled by SelectionDAG.
   bool shouldEmitSDCheck(const BasicBlock &BB) const;
   bool shouldEmitSDCheck(const BasicBlock &BB) const;
 
 
-  void adjustForColoring(const AllocaInst *From, const AllocaInst *To);
-
   bool runOnFunction(Function &Fn) override;
   bool runOnFunction(Function &Fn) override;
+
+  void copyToMachineFrameInfo(MachineFrameInfo &MFI) const;
 };
 };
 
 
 } // end namespace llvm
 } // end namespace llvm

+ 7 - 0
lib/CodeGen/GlobalISel/IRTranslator.cpp

@@ -26,6 +26,7 @@
 #include "llvm/CodeGen/MachineMemOperand.h"
 #include "llvm/CodeGen/MachineMemOperand.h"
 #include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/StackProtector.h"
 #include "llvm/CodeGen/TargetFrameLowering.h"
 #include "llvm/CodeGen/TargetFrameLowering.h"
 #include "llvm/CodeGen/TargetLowering.h"
 #include "llvm/CodeGen/TargetLowering.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
@@ -102,7 +103,9 @@ IRTranslator::IRTranslator() : MachineFunctionPass(ID) {
 }
 }
 
 
 void IRTranslator::getAnalysisUsage(AnalysisUsage &AU) const {
 void IRTranslator::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.addRequired<StackProtector>();
   AU.addRequired<TargetPassConfig>();
   AU.addRequired<TargetPassConfig>();
+  getSelectionDAGFallbackAnalysisUsage(AU);
   MachineFunctionPass::getAnalysisUsage(AU);
   MachineFunctionPass::getAnalysisUsage(AU);
 }
 }
 
 
@@ -1650,5 +1653,9 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
   assert(&MF->front() == &NewEntryBB &&
   assert(&MF->front() == &NewEntryBB &&
          "New entry wasn't next in the list of basic block!");
          "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;
   return false;
 }
 }

+ 1 - 0
lib/CodeGen/GlobalISel/InstructionSelect.cpp

@@ -56,6 +56,7 @@ InstructionSelect::InstructionSelect() : MachineFunctionPass(ID) {
 
 
 void InstructionSelect::getAnalysisUsage(AnalysisUsage &AU) const {
 void InstructionSelect::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired<TargetPassConfig>();
   AU.addRequired<TargetPassConfig>();
+  getSelectionDAGFallbackAnalysisUsage(AU);
   MachineFunctionPass::getAnalysisUsage(AU);
   MachineFunctionPass::getAnalysisUsage(AU);
 }
 }
 
 

+ 1 - 0
lib/CodeGen/GlobalISel/Legalizer.cpp

@@ -47,6 +47,7 @@ Legalizer::Legalizer() : MachineFunctionPass(ID) {
 
 
 void Legalizer::getAnalysisUsage(AnalysisUsage &AU) const {
 void Legalizer::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired<TargetPassConfig>();
   AU.addRequired<TargetPassConfig>();
+  getSelectionDAGFallbackAnalysisUsage(AU);
   MachineFunctionPass::getAnalysisUsage(AU);
   MachineFunctionPass::getAnalysisUsage(AU);
 }
 }
 
 

+ 5 - 0
lib/CodeGen/GlobalISel/Localizer.cpp

@@ -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,
 bool Localizer::isLocalUse(MachineOperand &MOUse, const MachineInstr &Def,
                            MachineBasicBlock *&InsertMBB) {
                            MachineBasicBlock *&InsertMBB) {
   MachineInstr &MIUse = *MOUse.getParent();
   MachineInstr &MIUse = *MOUse.getParent();

+ 1 - 0
lib/CodeGen/GlobalISel/RegBankSelect.cpp

@@ -105,6 +105,7 @@ void RegBankSelect::getAnalysisUsage(AnalysisUsage &AU) const {
     AU.addRequired<MachineBranchProbabilityInfo>();
     AU.addRequired<MachineBranchProbabilityInfo>();
   }
   }
   AU.addRequired<TargetPassConfig>();
   AU.addRequired<TargetPassConfig>();
+  getSelectionDAGFallbackAnalysisUsage(AU);
   MachineFunctionPass::getAnalysisUsage(AU);
   MachineFunctionPass::getAnalysisUsage(AU);
 }
 }
 
 

+ 5 - 0
lib/CodeGen/GlobalISel/Utils.cpp

@@ -18,6 +18,7 @@
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
 #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/StackProtector.h"
 #include "llvm/CodeGen/TargetInstrInfo.h"
 #include "llvm/CodeGen/TargetInstrInfo.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
@@ -233,3 +234,7 @@ APFloat llvm::getAPFloatFromSize(double Val, unsigned Size) {
   APF.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
   APF.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
   return APF;
   return APF;
 }
 }
+
+void llvm::getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU) {
+  AU.addPreserved<StackProtector>();
+}

+ 7 - 14
lib/CodeGen/LocalStackSlotAllocation.cpp

@@ -25,7 +25,6 @@
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/StackProtector.h"
 #include "llvm/CodeGen/TargetFrameLowering.h"
 #include "llvm/CodeGen/TargetFrameLowering.h"
 #include "llvm/CodeGen/TargetOpcodes.h"
 #include "llvm/CodeGen/TargetOpcodes.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
@@ -99,7 +98,6 @@ namespace {
 
 
     void getAnalysisUsage(AnalysisUsage &AU) const override {
     void getAnalysisUsage(AnalysisUsage &AU) const override {
       AU.setPreservesCFG();
       AU.setPreservesCFG();
-      AU.addRequired<StackProtector>();
       MachineFunctionPass::getAnalysisUsage(AU);
       MachineFunctionPass::getAnalysisUsage(AU);
     }
     }
   };
   };
@@ -109,12 +107,8 @@ namespace {
 char LocalStackSlotPass::ID = 0;
 char LocalStackSlotPass::ID = 0;
 
 
 char &llvm::LocalStackSlotAllocationID = LocalStackSlotPass::ID;
 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,
-                    "Local Stack Slot Allocation", false, false)
+INITIALIZE_PASS(LocalStackSlotPass, DEBUG_TYPE,
+                "Local Stack Slot Allocation", false, false)
 
 
 bool LocalStackSlotPass::runOnMachineFunction(MachineFunction &MF) {
 bool LocalStackSlotPass::runOnMachineFunction(MachineFunction &MF) {
   MachineFrameInfo &MFI = MF.getFrameInfo();
   MachineFrameInfo &MFI = MF.getFrameInfo();
@@ -202,7 +196,6 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
     TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
     TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
   int64_t Offset = 0;
   int64_t Offset = 0;
   unsigned MaxAlign = 0;
   unsigned MaxAlign = 0;
-  StackProtector *SP = &getAnalysis<StackProtector>();
 
 
   // Make sure that the stack protector comes before the local variables on the
   // Make sure that the stack protector comes before the local variables on the
   // stack.
   // stack.
@@ -222,16 +215,16 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
       if (MFI.getStackProtectorIndex() == (int)i)
       if (MFI.getStackProtectorIndex() == (int)i)
         continue;
         continue;
 
 
-      switch (SP->getSSPLayout(MFI.getObjectAllocation(i))) {
-      case StackProtector::SSPLK_None:
+      switch (MFI.getObjectSSPLayout(i)) {
+      case MachineFrameInfo::SSPLK_None:
         continue;
         continue;
-      case StackProtector::SSPLK_SmallArray:
+      case MachineFrameInfo::SSPLK_SmallArray:
         SmallArrayObjs.insert(i);
         SmallArrayObjs.insert(i);
         continue;
         continue;
-      case StackProtector::SSPLK_AddrOf:
+      case MachineFrameInfo::SSPLK_AddrOf:
         AddrOfObjs.insert(i);
         AddrOfObjs.insert(i);
         continue;
         continue;
-      case StackProtector::SSPLK_LargeArray:
+      case MachineFrameInfo::SSPLK_LargeArray:
         LargeArrayObjs.insert(i);
         LargeArrayObjs.insert(i);
         continue;
         continue;
       }
       }

+ 0 - 2
lib/CodeGen/MachineFunctionPass.cpp

@@ -24,7 +24,6 @@
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/StackProtector.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/Function.h"
 
 
@@ -85,7 +84,6 @@ void MachineFunctionPass::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addPreserved<MemoryDependenceWrapperPass>();
   AU.addPreserved<MemoryDependenceWrapperPass>();
   AU.addPreserved<ScalarEvolutionWrapperPass>();
   AU.addPreserved<ScalarEvolutionWrapperPass>();
   AU.addPreserved<SCEVAAWrapperPass>();
   AU.addPreserved<SCEVAAWrapperPass>();
-  AU.addPreserved<StackProtector>();
 
 
   FunctionPass::getAnalysisUsage(AU);
   FunctionPass::getAnalysisUsage(AU);
 }
 }

+ 5 - 9
lib/CodeGen/PrologEpilogInserter.cpp

@@ -38,7 +38,6 @@
 #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
 #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/RegisterScavenging.h"
 #include "llvm/CodeGen/RegisterScavenging.h"
-#include "llvm/CodeGen/StackProtector.h"
 #include "llvm/CodeGen/TargetFrameLowering.h"
 #include "llvm/CodeGen/TargetFrameLowering.h"
 #include "llvm/CodeGen/TargetInstrInfo.h"
 #include "llvm/CodeGen/TargetInstrInfo.h"
 #include "llvm/CodeGen/TargetOpcodes.h"
 #include "llvm/CodeGen/TargetOpcodes.h"
@@ -143,7 +142,6 @@ INITIALIZE_PASS_BEGIN(PEI, DEBUG_TYPE, "Prologue/Epilogue Insertion", false,
                       false)
                       false)
 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
-INITIALIZE_PASS_DEPENDENCY(StackProtector)
 INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass)
 INITIALIZE_PASS_DEPENDENCY(MachineOptimizationRemarkEmitterPass)
 INITIALIZE_PASS_END(PEI, DEBUG_TYPE,
 INITIALIZE_PASS_END(PEI, DEBUG_TYPE,
                     "Prologue/Epilogue Insertion & Frame Finalization", false,
                     "Prologue/Epilogue Insertion & Frame Finalization", false,
@@ -160,7 +158,6 @@ void PEI::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.setPreservesCFG();
   AU.setPreservesCFG();
   AU.addPreserved<MachineLoopInfo>();
   AU.addPreserved<MachineLoopInfo>();
   AU.addPreserved<MachineDominatorTree>();
   AU.addPreserved<MachineDominatorTree>();
-  AU.addRequired<StackProtector>();
   AU.addRequired<MachineOptimizationRemarkEmitterPass>();
   AU.addRequired<MachineOptimizationRemarkEmitterPass>();
   MachineFunctionPass::getAnalysisUsage(AU);
   MachineFunctionPass::getAnalysisUsage(AU);
 }
 }
@@ -695,7 +692,6 @@ AssignProtectedObjSet(const StackObjSet &UnassignedObjs,
 /// abstract stack objects.
 /// abstract stack objects.
 void PEI::calculateFrameObjectOffsets(MachineFunction &MF) {
 void PEI::calculateFrameObjectOffsets(MachineFunction &MF) {
   const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
   const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
-  StackProtector *SP = &getAnalysis<StackProtector>();
 
 
   bool StackGrowsDown =
   bool StackGrowsDown =
     TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
     TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
@@ -844,16 +840,16 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &MF) {
           EHRegNodeFrameIndex == (int)i)
           EHRegNodeFrameIndex == (int)i)
         continue;
         continue;
 
 
-      switch (SP->getSSPLayout(MFI.getObjectAllocation(i))) {
-      case StackProtector::SSPLK_None:
+      switch (MFI.getObjectSSPLayout(i)) {
+      case MachineFrameInfo::SSPLK_None:
         continue;
         continue;
-      case StackProtector::SSPLK_SmallArray:
+      case MachineFrameInfo::SSPLK_SmallArray:
         SmallArrayObjs.insert(i);
         SmallArrayObjs.insert(i);
         continue;
         continue;
-      case StackProtector::SSPLK_AddrOf:
+      case MachineFrameInfo::SSPLK_AddrOf:
         AddrOfObjs.insert(i);
         AddrOfObjs.insert(i);
         continue;
         continue;
-      case StackProtector::SSPLK_LargeArray:
+      case MachineFrameInfo::SSPLK_LargeArray:
         LargeArrayObjs.insert(i);
         LargeArrayObjs.insert(i);
         continue;
         continue;
       }
       }

+ 6 - 0
lib/CodeGen/ResetMachineFunctionPass.cpp

@@ -18,6 +18,7 @@
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/StackProtector.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Debug.h"
@@ -44,6 +45,11 @@ namespace {
 
 
     StringRef getPassName() const override { return "ResetMachineFunction"; }
     StringRef getPassName() const override { return "ResetMachineFunction"; }
 
 
+    void getAnalysisUsage(AnalysisUsage &AU) const override {
+      AU.addPreserved<StackProtector>();
+      MachineFunctionPass::getAnalysisUsage(AU);
+    }
+
     bool runOnMachineFunction(MachineFunction &MF) override {
     bool runOnMachineFunction(MachineFunction &MF) override {
       // No matter what happened, whether we successfully selected the function
       // 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
       // or not, nothing is going to use the vreg types after us. Make sure they

+ 4 - 2
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

@@ -328,7 +328,6 @@ void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
     AU.addRequired<AAResultsWrapperPass>();
     AU.addRequired<AAResultsWrapperPass>();
   AU.addRequired<GCModuleInfo>();
   AU.addRequired<GCModuleInfo>();
   AU.addRequired<StackProtector>();
   AU.addRequired<StackProtector>();
-  AU.addPreserved<StackProtector>();
   AU.addPreserved<GCModuleInfo>();
   AU.addPreserved<GCModuleInfo>();
   AU.addRequired<TargetLibraryInfoWrapperPass>();
   AU.addRequired<TargetLibraryInfoWrapperPass>();
   AU.addRequired<TargetTransformInfoWrapperPass>();
   AU.addRequired<TargetTransformInfoWrapperPass>();
@@ -1544,6 +1543,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
   processDbgDeclares(FuncInfo);
   processDbgDeclares(FuncInfo);
 
 
   // Iterate over all basic blocks in the function.
   // Iterate over all basic blocks in the function.
+  StackProtector &SP = getAnalysis<StackProtector>();
   for (const BasicBlock *LLVMBB : RPOT) {
   for (const BasicBlock *LLVMBB : RPOT) {
     if (OptLevel != CodeGenOpt::None) {
     if (OptLevel != CodeGenOpt::None) {
       bool AllPredsVisited = true;
       bool AllPredsVisited = true;
@@ -1713,7 +1713,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
       FastIS->recomputeInsertPt();
       FastIS->recomputeInsertPt();
     }
     }
 
 
-    if (getAnalysis<StackProtector>().shouldEmitSDCheck(*LLVMBB)) {
+    if (SP.shouldEmitSDCheck(*LLVMBB)) {
       bool FunctionBasedInstrumentation =
       bool FunctionBasedInstrumentation =
           TLI->getSSPStackGuardCheck(*Fn.getParent());
           TLI->getSSPStackGuardCheck(*Fn.getParent());
       SDB->SPDescriptor.initialize(LLVMBB, FuncInfo->MBBMap[LLVMBB],
       SDB->SPDescriptor.initialize(LLVMBB, FuncInfo->MBBMap[LLVMBB],
@@ -1746,6 +1746,8 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
     ElidedArgCopyInstrs.clear();
     ElidedArgCopyInstrs.clear();
   }
   }
 
 
+  SP.copyToMachineFrameInfo(MF->getFrameInfo());
+
   propagateSwiftErrorVRegs(FuncInfo);
   propagateSwiftErrorVRegs(FuncInfo);
 
 
   delete FastIS;
   delete FastIS;

+ 11 - 10
lib/CodeGen/StackColoring.cpp

@@ -39,7 +39,6 @@
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/SelectionDAGNodes.h"
 #include "llvm/CodeGen/SelectionDAGNodes.h"
 #include "llvm/CodeGen/SlotIndexes.h"
 #include "llvm/CodeGen/SlotIndexes.h"
-#include "llvm/CodeGen/StackProtector.h"
 #include "llvm/CodeGen/TargetOpcodes.h"
 #include "llvm/CodeGen/TargetOpcodes.h"
 #include "llvm/CodeGen/WinEHFuncInfo.h"
 #include "llvm/CodeGen/WinEHFuncInfo.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/Config/llvm-config.h"
@@ -423,9 +422,6 @@ class StackColoring : public MachineFunctionPass {
   /// SlotIndex analysis object.
   /// SlotIndex analysis object.
   SlotIndexes *Indexes;
   SlotIndexes *Indexes;
 
 
-  /// The stack protector object.
-  StackProtector *SP;
-
   /// The list of lifetime markers found. These markers are to be removed
   /// The list of lifetime markers found. These markers are to be removed
   /// once the coloring is done.
   /// once the coloring is done.
   SmallVector<MachineInstr*, 8> Markers;
   SmallVector<MachineInstr*, 8> Markers;
@@ -524,13 +520,11 @@ char &llvm::StackColoringID = StackColoring::ID;
 INITIALIZE_PASS_BEGIN(StackColoring, DEBUG_TYPE,
 INITIALIZE_PASS_BEGIN(StackColoring, DEBUG_TYPE,
                       "Merge disjoint stack slots", false, false)
                       "Merge disjoint stack slots", false, false)
 INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
 INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
-INITIALIZE_PASS_DEPENDENCY(StackProtector)
 INITIALIZE_PASS_END(StackColoring, DEBUG_TYPE,
 INITIALIZE_PASS_END(StackColoring, DEBUG_TYPE,
                     "Merge disjoint stack slots", false, false)
                     "Merge disjoint stack slots", false, false)
 
 
 void StackColoring::getAnalysisUsage(AnalysisUsage &AU) const {
 void StackColoring::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired<SlotIndexes>();
   AU.addRequired<SlotIndexes>();
-  AU.addRequired<StackProtector>();
   MachineFunctionPass::getAnalysisUsage(AU);
   MachineFunctionPass::getAnalysisUsage(AU);
 }
 }
 
 
@@ -936,9 +930,17 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
     MergedAllocas.insert(From);
     MergedAllocas.insert(From);
     MergedAllocas.insert(To);
     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
     // 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.
     // variable, so undef out the use to make the verifier happy.
@@ -1139,7 +1141,6 @@ bool StackColoring::runOnMachineFunction(MachineFunction &Func) {
   MF = &Func;
   MF = &Func;
   MFI = &MF->getFrameInfo();
   MFI = &MF->getFrameInfo();
   Indexes = &getAnalysis<SlotIndexes>();
   Indexes = &getAnalysis<SlotIndexes>();
-  SP = &getAnalysis<StackProtector>();
   BlockLiveness.clear();
   BlockLiveness.clear();
   BasicBlocks.clear();
   BasicBlocks.clear();
   BasicBlockNumbering.clear();
   BasicBlockNumbering.clear();

+ 30 - 32
lib/CodeGen/StackProtector.cpp

@@ -70,32 +70,6 @@ INITIALIZE_PASS_END(StackProtector, DEBUG_TYPE,
 
 
 FunctionPass *llvm::createStackProtectorPass() { return new StackProtector(); }
 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 {
 void StackProtector::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired<TargetPassConfig>();
   AU.addRequired<TargetPassConfig>();
   AU.addPreserved<DominatorTreeWrapperPass>();
   AU.addPreserved<DominatorTreeWrapperPass>();
@@ -289,18 +263,21 @@ bool StackProtector::RequiresStackProtector() {
             if (CI->getLimitedValue(SSPBufferSize) >= SSPBufferSize) {
             if (CI->getLimitedValue(SSPBufferSize) >= SSPBufferSize) {
               // A call to alloca with size >= SSPBufferSize requires
               // A call to alloca with size >= SSPBufferSize requires
               // stack protectors.
               // stack protectors.
-              Layout.insert(std::make_pair(AI, SSPLK_LargeArray));
+              Layout.insert(std::make_pair(AI,
+                                           MachineFrameInfo::SSPLK_LargeArray));
               ORE.emit(RemarkBuilder);
               ORE.emit(RemarkBuilder);
               NeedsProtector = true;
               NeedsProtector = true;
             } else if (Strong) {
             } else if (Strong) {
               // Require protectors for all alloca calls in strong mode.
               // 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);
               ORE.emit(RemarkBuilder);
               NeedsProtector = true;
               NeedsProtector = true;
             }
             }
           } else {
           } else {
             // A call to alloca with a variable size requires protectors.
             // 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);
             ORE.emit(RemarkBuilder);
             NeedsProtector = true;
             NeedsProtector = true;
           }
           }
@@ -309,8 +286,9 @@ bool StackProtector::RequiresStackProtector() {
 
 
         bool IsLarge = false;
         bool IsLarge = false;
         if (ContainsProtectableArray(AI->getAllocatedType(), IsLarge, Strong)) {
         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([&]() {
           ORE.emit([&]() {
             return OptimizationRemark(DEBUG_TYPE, "StackProtectorBuffer", &I)
             return OptimizationRemark(DEBUG_TYPE, "StackProtectorBuffer", &I)
                    << "Stack protection applied to function "
                    << "Stack protection applied to function "
@@ -324,7 +302,7 @@ bool StackProtector::RequiresStackProtector() {
 
 
         if (Strong && HasAddressTaken(AI)) {
         if (Strong && HasAddressTaken(AI)) {
           ++NumAddrTaken;
           ++NumAddrTaken;
-          Layout.insert(std::make_pair(AI, SSPLK_AddrOf));
+          Layout.insert(std::make_pair(AI, MachineFrameInfo::SSPLK_AddrOf));
           ORE.emit([&]() {
           ORE.emit([&]() {
             return OptimizationRemark(DEBUG_TYPE, "StackProtectorAddressTaken",
             return OptimizationRemark(DEBUG_TYPE, "StackProtectorAddressTaken",
                                       &I)
                                       &I)
@@ -534,3 +512,23 @@ BasicBlock *StackProtector::CreateFailBB() {
 bool StackProtector::shouldEmitSDCheck(const BasicBlock &BB) const {
 bool StackProtector::shouldEmitSDCheck(const BasicBlock &BB) const {
   return HasPrologue && !HasIRCheck && dyn_cast<ReturnInst>(BB.getTerminator());
   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);
+  }
+}

+ 8 - 0
lib/Target/Mips/MipsISelDAGToDAG.cpp

@@ -24,6 +24,7 @@
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/SelectionDAGNodes.h"
 #include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/StackProtector.h"
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/GlobalValue.h"
 #include "llvm/IR/GlobalValue.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Instructions.h"
@@ -46,6 +47,13 @@ using namespace llvm;
 // instructions for SelectionDAG operations.
 // 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) {
 bool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
   Subtarget = &static_cast<const MipsSubtarget &>(MF.getSubtarget());
   Subtarget = &static_cast<const MipsSubtarget &>(MF.getSubtarget());
   bool Ret = SelectionDAGISel::runOnMachineFunction(MF);
   bool Ret = SelectionDAGISel::runOnMachineFunction(MF);

+ 2 - 0
lib/Target/Mips/MipsISelDAGToDAG.h

@@ -41,6 +41,8 @@ public:
 
 
   bool runOnMachineFunction(MachineFunction &MF) override;
   bool runOnMachineFunction(MachineFunction &MF) override;
 
 
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+
 protected:
 protected:
   SDNode *getGlobalBaseReg();
   SDNode *getGlobalBaseReg();
 
 

+ 2 - 0
lib/Target/Mips/MipsModuleISelDAGToDAG.cpp

@@ -11,6 +11,7 @@
 #include "Mips.h"
 #include "Mips.h"
 #include "MipsTargetMachine.h"
 #include "MipsTargetMachine.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/CodeGen/StackProtector.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/raw_ostream.h"
 
 
@@ -32,6 +33,7 @@ namespace {
 
 
     void getAnalysisUsage(AnalysisUsage &AU) const override {
     void getAnalysisUsage(AnalysisUsage &AU) const override {
       AU.addRequired<TargetPassConfig>();
       AU.addRequired<TargetPassConfig>();
+      AU.addPreserved<StackProtector>();
       MachineFunctionPass::getAnalysisUsage(AU);
       MachineFunctionPass::getAnalysisUsage(AU);
     }
     }