003 File Manager
Current Path:
/usr/src/contrib/llvm-project/llvm/lib/Target/X86
usr
/
src
/
contrib
/
llvm-project
/
llvm
/
lib
/
Target
/
X86
/
📁
..
📁
AsmParser
📁
Disassembler
📄
ImmutableGraph.h
(15.15 KB)
📁
MCTargetDesc
📁
TargetInfo
📄
X86.h
(7.41 KB)
📄
X86.td
(68.44 KB)
📄
X86AsmPrinter.cpp
(27.18 KB)
📄
X86AsmPrinter.h
(5.96 KB)
📄
X86AvoidStoreForwardingBlocks.cpp
(27.94 KB)
📄
X86AvoidTrailingCall.cpp
(4.91 KB)
📄
X86CallFrameOptimization.cpp
(23.07 KB)
📄
X86CallLowering.cpp
(17.62 KB)
📄
X86CallLowering.h
(1.74 KB)
📄
X86CallingConv.cpp
(13.34 KB)
📄
X86CallingConv.h
(1.09 KB)
📄
X86CallingConv.td
(46.15 KB)
📄
X86CmovConversion.cpp
(34.07 KB)
📄
X86CondBrFolding.cpp
(18.4 KB)
📄
X86DiscriminateMemOps.cpp
(7.11 KB)
📄
X86DomainReassignment.cpp
(25.87 KB)
📄
X86EvexToVex.cpp
(8.8 KB)
📄
X86ExpandPseudo.cpp
(16.95 KB)
📄
X86FastISel.cpp
(139.28 KB)
📄
X86FixupBWInsts.cpp
(18.09 KB)
📄
X86FixupLEAs.cpp
(24.44 KB)
📄
X86FixupSetCC.cpp
(4.44 KB)
📄
X86FlagsCopyLowering.cpp
(40.36 KB)
📄
X86FloatingPoint.cpp
(62.66 KB)
📄
X86FrameLowering.cpp
(138.71 KB)
📄
X86FrameLowering.h
(11.64 KB)
📄
X86GenRegisterBankInfo.def
(3.32 KB)
📄
X86ISelDAGToDAG.cpp
(208.37 KB)
📄
X86ISelLowering.cpp
(1.94 MB)
📄
X86ISelLowering.h
(60.88 KB)
📄
X86IndirectBranchTracking.cpp
(6.17 KB)
📄
X86IndirectThunks.cpp
(9.78 KB)
📄
X86InsertPrefetch.cpp
(9.64 KB)
📄
X86InsertWait.cpp
(4.47 KB)
📄
X86Instr3DNow.td
(5.24 KB)
📄
X86InstrAMX.td
(5.6 KB)
📄
X86InstrAVX512.td
(653.76 KB)
📄
X86InstrArithmetic.td
(75.61 KB)
📄
X86InstrBuilder.h
(8.45 KB)
📄
X86InstrCMovSetCC.td
(5.76 KB)
📄
X86InstrCompiler.td
(95.78 KB)
📄
X86InstrControl.td
(20.53 KB)
📄
X86InstrExtension.td
(11.64 KB)
📄
X86InstrFMA.td
(33.23 KB)
📄
X86InstrFMA3Info.cpp
(6.21 KB)
📄
X86InstrFMA3Info.h
(3.25 KB)
📄
X86InstrFPStack.td
(39.52 KB)
📄
X86InstrFoldTables.cpp
(393.01 KB)
📄
X86InstrFoldTables.h
(3.03 KB)
📄
X86InstrFormats.td
(41.05 KB)
📄
X86InstrFragmentsSIMD.td
(61.14 KB)
📄
X86InstrInfo.cpp
(322.72 KB)
📄
X86InstrInfo.h
(29.34 KB)
📄
X86InstrInfo.td
(169.76 KB)
📄
X86InstrMMX.td
(29.55 KB)
📄
X86InstrMPX.td
(3.63 KB)
📄
X86InstrSGX.td
(1.12 KB)
📄
X86InstrSSE.td
(385.01 KB)
📄
X86InstrSVM.td
(2.16 KB)
📄
X86InstrShiftRotate.td
(49.56 KB)
📄
X86InstrSystem.td
(34.03 KB)
📄
X86InstrTSX.td
(2.1 KB)
📄
X86InstrVMX.td
(3.53 KB)
📄
X86InstrVecCompiler.td
(21.09 KB)
📄
X86InstrXOP.td
(23.81 KB)
📄
X86InstructionSelector.cpp
(61.11 KB)
📄
X86InterleavedAccess.cpp
(32.7 KB)
📄
X86IntrinsicsInfo.h
(73.96 KB)
📄
X86LegalizerInfo.cpp
(15.6 KB)
📄
X86LegalizerInfo.h
(1.65 KB)
📄
X86LoadValueInjectionLoadHardening.cpp
(32.4 KB)
📄
X86LoadValueInjectionRetHardening.cpp
(4.93 KB)
📄
X86MCInstLower.cpp
(96.53 KB)
📄
X86MachineFunctionInfo.cpp
(1.1 KB)
📄
X86MachineFunctionInfo.h
(8.87 KB)
📄
X86MacroFusion.cpp
(2.62 KB)
📄
X86MacroFusion.h
(992 B)
📄
X86OptimizeLEAs.cpp
(27.47 KB)
📄
X86PadShortFunction.cpp
(7.33 KB)
📄
X86PartialReduction.cpp
(15.46 KB)
📄
X86PfmCounters.td
(10.18 KB)
📄
X86RegisterBankInfo.cpp
(10.55 KB)
📄
X86RegisterBankInfo.h
(2.87 KB)
📄
X86RegisterBanks.td
(629 B)
📄
X86RegisterInfo.cpp
(29 KB)
📄
X86RegisterInfo.h
(5.61 KB)
📄
X86RegisterInfo.td
(26.07 KB)
📄
X86SchedBroadwell.td
(69.45 KB)
📄
X86SchedHaswell.td
(73.96 KB)
📄
X86SchedPredicates.td
(4.23 KB)
📄
X86SchedSandyBridge.td
(50 KB)
📄
X86SchedSkylakeClient.td
(74.65 KB)
📄
X86SchedSkylakeServer.td
(113.85 KB)
📄
X86Schedule.td
(36.9 KB)
📄
X86ScheduleAtom.td
(38.26 KB)
📄
X86ScheduleBdVer2.td
(56.78 KB)
📄
X86ScheduleBtVer2.td
(46.98 KB)
📄
X86ScheduleSLM.td
(22.91 KB)
📄
X86ScheduleZnver1.td
(48.97 KB)
📄
X86ScheduleZnver2.td
(48.12 KB)
📄
X86SelectionDAGInfo.cpp
(12.02 KB)
📄
X86SelectionDAGInfo.h
(1.8 KB)
📄
X86ShuffleDecodeConstantPool.cpp
(11.22 KB)
📄
X86ShuffleDecodeConstantPool.h
(2.13 KB)
📄
X86SpeculativeExecutionSideEffectSuppression.cpp
(6.97 KB)
📄
X86SpeculativeLoadHardening.cpp
(93.16 KB)
📄
X86Subtarget.cpp
(13.25 KB)
📄
X86Subtarget.h
(32.08 KB)
📄
X86TargetMachine.cpp
(18.88 KB)
📄
X86TargetMachine.h
(2.04 KB)
📄
X86TargetObjectFile.cpp
(2.61 KB)
📄
X86TargetObjectFile.h
(2.13 KB)
📄
X86TargetTransformInfo.cpp
(189.14 KB)
📄
X86TargetTransformInfo.h
(9.63 KB)
📄
X86VZeroUpper.cpp
(12.59 KB)
📄
X86WinAllocaExpander.cpp
(9.54 KB)
📄
X86WinEHState.cpp
(28.97 KB)
Editing: X86WinAllocaExpander.cpp
//===----- X86WinAllocaExpander.cpp - Expand WinAlloca pseudo instruction -===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines a pass that expands WinAlloca pseudo-instructions. // // It performs a conservative analysis to determine whether each allocation // falls within a region of the stack that is safe to use, or whether stack // probes must be emitted. // //===----------------------------------------------------------------------===// #include "X86.h" #include "X86InstrBuilder.h" #include "X86InstrInfo.h" #include "X86MachineFunctionInfo.h" #include "X86Subtarget.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/PostOrderIterator.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/IR/Function.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; namespace { class X86WinAllocaExpander : public MachineFunctionPass { public: X86WinAllocaExpander() : MachineFunctionPass(ID) {} bool runOnMachineFunction(MachineFunction &MF) override; private: /// Strategies for lowering a WinAlloca. enum Lowering { TouchAndSub, Sub, Probe }; /// Deterministic-order map from WinAlloca instruction to desired lowering. typedef MapVector<MachineInstr*, Lowering> LoweringMap; /// Compute which lowering to use for each WinAlloca instruction. void computeLowerings(MachineFunction &MF, LoweringMap& Lowerings); /// Get the appropriate lowering based on current offset and amount. Lowering getLowering(int64_t CurrentOffset, int64_t AllocaAmount); /// Lower a WinAlloca instruction. void lower(MachineInstr* MI, Lowering L); MachineRegisterInfo *MRI = nullptr; const X86Subtarget *STI = nullptr; const TargetInstrInfo *TII = nullptr; const X86RegisterInfo *TRI = nullptr; unsigned StackPtr = 0; unsigned SlotSize = 0; int64_t StackProbeSize = 0; bool NoStackArgProbe = false; StringRef getPassName() const override { return "X86 WinAlloca Expander"; } static char ID; }; char X86WinAllocaExpander::ID = 0; } // end anonymous namespace FunctionPass *llvm::createX86WinAllocaExpander() { return new X86WinAllocaExpander(); } /// Return the allocation amount for a WinAlloca instruction, or -1 if unknown. static int64_t getWinAllocaAmount(MachineInstr *MI, MachineRegisterInfo *MRI) { assert(MI->getOpcode() == X86::WIN_ALLOCA_32 || MI->getOpcode() == X86::WIN_ALLOCA_64); assert(MI->getOperand(0).isReg()); Register AmountReg = MI->getOperand(0).getReg(); MachineInstr *Def = MRI->getUniqueVRegDef(AmountReg); if (!Def || (Def->getOpcode() != X86::MOV32ri && Def->getOpcode() != X86::MOV64ri) || !Def->getOperand(1).isImm()) return -1; return Def->getOperand(1).getImm(); } X86WinAllocaExpander::Lowering X86WinAllocaExpander::getLowering(int64_t CurrentOffset, int64_t AllocaAmount) { // For a non-constant amount or a large amount, we have to probe. if (AllocaAmount < 0 || AllocaAmount > StackProbeSize) return Probe; // If it fits within the safe region of the stack, just subtract. if (CurrentOffset + AllocaAmount <= StackProbeSize) return Sub; // Otherwise, touch the current tip of the stack, then subtract. return TouchAndSub; } static bool isPushPop(const MachineInstr &MI) { switch (MI.getOpcode()) { case X86::PUSH32i8: case X86::PUSH32r: case X86::PUSH32rmm: case X86::PUSH32rmr: case X86::PUSHi32: case X86::PUSH64i8: case X86::PUSH64r: case X86::PUSH64rmm: case X86::PUSH64rmr: case X86::PUSH64i32: case X86::POP32r: case X86::POP64r: return true; default: return false; } } void X86WinAllocaExpander::computeLowerings(MachineFunction &MF, LoweringMap &Lowerings) { // Do a one-pass reverse post-order walk of the CFG to conservatively estimate // the offset between the stack pointer and the lowest touched part of the // stack, and use that to decide how to lower each WinAlloca instruction. // Initialize OutOffset[B], the stack offset at exit from B, to something big. DenseMap<MachineBasicBlock *, int64_t> OutOffset; for (MachineBasicBlock &MBB : MF) OutOffset[&MBB] = INT32_MAX; // Note: we don't know the offset at the start of the entry block since the // prologue hasn't been inserted yet, and how much that will adjust the stack // pointer depends on register spills, which have not been computed yet. // Compute the reverse post-order. ReversePostOrderTraversal<MachineFunction*> RPO(&MF); for (MachineBasicBlock *MBB : RPO) { int64_t Offset = -1; for (MachineBasicBlock *Pred : MBB->predecessors()) Offset = std::max(Offset, OutOffset[Pred]); if (Offset == -1) Offset = INT32_MAX; for (MachineInstr &MI : *MBB) { if (MI.getOpcode() == X86::WIN_ALLOCA_32 || MI.getOpcode() == X86::WIN_ALLOCA_64) { // A WinAlloca moves StackPtr, and potentially touches it. int64_t Amount = getWinAllocaAmount(&MI, MRI); Lowering L = getLowering(Offset, Amount); Lowerings[&MI] = L; switch (L) { case Sub: Offset += Amount; break; case TouchAndSub: Offset = Amount; break; case Probe: Offset = 0; break; } } else if (MI.isCall() || isPushPop(MI)) { // Calls, pushes and pops touch the tip of the stack. Offset = 0; } else if (MI.getOpcode() == X86::ADJCALLSTACKUP32 || MI.getOpcode() == X86::ADJCALLSTACKUP64) { Offset -= MI.getOperand(0).getImm(); } else if (MI.getOpcode() == X86::ADJCALLSTACKDOWN32 || MI.getOpcode() == X86::ADJCALLSTACKDOWN64) { Offset += MI.getOperand(0).getImm(); } else if (MI.modifiesRegister(StackPtr, TRI)) { // Any other modification of SP means we've lost track of it. Offset = INT32_MAX; } } OutOffset[MBB] = Offset; } } static unsigned getSubOpcode(bool Is64Bit, int64_t Amount) { if (Is64Bit) return isInt<8>(Amount) ? X86::SUB64ri8 : X86::SUB64ri32; return isInt<8>(Amount) ? X86::SUB32ri8 : X86::SUB32ri; } void X86WinAllocaExpander::lower(MachineInstr* MI, Lowering L) { DebugLoc DL = MI->getDebugLoc(); MachineBasicBlock *MBB = MI->getParent(); MachineBasicBlock::iterator I = *MI; int64_t Amount = getWinAllocaAmount(MI, MRI); if (Amount == 0) { MI->eraseFromParent(); return; } // These two variables differ on x32, which is a 64-bit target with a // 32-bit alloca. bool Is64Bit = STI->is64Bit(); bool Is64BitAlloca = MI->getOpcode() == X86::WIN_ALLOCA_64; assert(SlotSize == 4 || SlotSize == 8); switch (L) { case TouchAndSub: { assert(Amount >= SlotSize); // Use a push to touch the top of the stack. unsigned RegA = Is64Bit ? X86::RAX : X86::EAX; BuildMI(*MBB, I, DL, TII->get(Is64Bit ? X86::PUSH64r : X86::PUSH32r)) .addReg(RegA, RegState::Undef); Amount -= SlotSize; if (!Amount) break; // Fall through to make any remaining adjustment. LLVM_FALLTHROUGH; } case Sub: assert(Amount > 0); if (Amount == SlotSize) { // Use push to save size. unsigned RegA = Is64Bit ? X86::RAX : X86::EAX; BuildMI(*MBB, I, DL, TII->get(Is64Bit ? X86::PUSH64r : X86::PUSH32r)) .addReg(RegA, RegState::Undef); } else { // Sub. BuildMI(*MBB, I, DL, TII->get(getSubOpcode(Is64BitAlloca, Amount)), StackPtr) .addReg(StackPtr) .addImm(Amount); } break; case Probe: if (!NoStackArgProbe) { // The probe lowering expects the amount in RAX/EAX. unsigned RegA = Is64BitAlloca ? X86::RAX : X86::EAX; BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::COPY), RegA) .addReg(MI->getOperand(0).getReg()); // Do the probe. STI->getFrameLowering()->emitStackProbe(*MBB->getParent(), *MBB, MI, DL, /*InProlog=*/false); } else { // Sub BuildMI(*MBB, I, DL, TII->get(Is64BitAlloca ? X86::SUB64rr : X86::SUB32rr), StackPtr) .addReg(StackPtr) .addReg(MI->getOperand(0).getReg()); } break; } Register AmountReg = MI->getOperand(0).getReg(); MI->eraseFromParent(); // Delete the definition of AmountReg. if (MRI->use_empty(AmountReg)) if (MachineInstr *AmountDef = MRI->getUniqueVRegDef(AmountReg)) AmountDef->eraseFromParent(); } bool X86WinAllocaExpander::runOnMachineFunction(MachineFunction &MF) { if (!MF.getInfo<X86MachineFunctionInfo>()->hasWinAlloca()) return false; MRI = &MF.getRegInfo(); STI = &MF.getSubtarget<X86Subtarget>(); TII = STI->getInstrInfo(); TRI = STI->getRegisterInfo(); StackPtr = TRI->getStackRegister(); SlotSize = TRI->getSlotSize(); StackProbeSize = 4096; if (MF.getFunction().hasFnAttribute("stack-probe-size")) { MF.getFunction() .getFnAttribute("stack-probe-size") .getValueAsString() .getAsInteger(0, StackProbeSize); } NoStackArgProbe = MF.getFunction().hasFnAttribute("no-stack-arg-probe"); if (NoStackArgProbe) StackProbeSize = INT64_MAX; LoweringMap Lowerings; computeLowerings(MF, Lowerings); for (auto &P : Lowerings) lower(P.first, P.second); return true; }
Upload File
Create Folder