diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/MachineOutliner.cpp | 87 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 49 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrInfo.h | 153 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.cpp | 41 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.h | 138 |
5 files changed, 271 insertions, 197 deletions
diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp index a0cf8eab2af..36163538f4e 100644 --- a/llvm/lib/CodeGen/MachineOutliner.cpp +++ b/llvm/lib/CodeGen/MachineOutliner.cpp @@ -87,6 +87,9 @@ struct Candidate { /// \p OutlinedFunctions. size_t FunctionIdx; + /// Target-defined unsigned defining how to emit a call for this candidate. + unsigned CallClass = 0; + /// \brief The number of instructions that would be saved by outlining every /// candidate of this type. /// @@ -96,8 +99,9 @@ struct Candidate { /// for some given candidate. unsigned Benefit = 0; - Candidate(size_t StartIdx, size_t Len, size_t FunctionIdx) - : StartIdx(StartIdx), Len(Len), FunctionIdx(FunctionIdx) {} + Candidate(size_t StartIdx, size_t Len, size_t FunctionIdx, unsigned CallClass) + : StartIdx(StartIdx), Len(Len), FunctionIdx(FunctionIdx), + CallClass(CallClass) {} Candidate() {} @@ -127,15 +131,14 @@ struct OutlinedFunction { /// The number of instructions this function would save. unsigned Benefit = 0; - /// \brief Set to true if candidates for this outlined function should be - /// replaced with tail calls to this OutlinedFunction. - bool IsTailCall = false; + /// Target-defined unsigned defining how to emit the frame for this function. + unsigned FrameClass = 0; OutlinedFunction(size_t Name, size_t OccurrenceCount, const std::vector<unsigned> &Sequence, unsigned Benefit, - bool IsTailCall) + unsigned FrameClass) : Name(Name), OccurrenceCount(OccurrenceCount), Sequence(Sequence), - Benefit(Benefit), IsTailCall(IsTailCall) {} + Benefit(Benefit), FrameClass(FrameClass) {} }; /// Represents an undefined index in the suffix tree. @@ -842,9 +845,18 @@ MachineOutliner::findCandidates(SuffixTree &ST, const TargetInstrInfo &TII, // Figure out if this candidate is beneficial. size_t StringLen = Leaf->ConcatLen - Leaf->size(); size_t CallOverhead = 0; - size_t FrameOverhead = 0; size_t SequenceOverhead = StringLen; + // If this is a beneficial class of candidate, then every one is stored in + // this vector. + std::vector<Candidate> CandidatesForRepeatedSeq; + + // Used for getOutliningFrameOverhead. + // FIXME: CandidatesForRepeatedSeq and this should be combined. + std::vector< + std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>> + CandidateClass; + // Figure out the call overhead for each instance of the sequence. for (auto &ChildPair : Parent.Children) { SuffixTreeNode *M = ChildPair.second; @@ -854,16 +866,24 @@ MachineOutliner::findCandidates(SuffixTree &ST, const TargetInstrInfo &TII, MachineBasicBlock::iterator StartIt = Mapper.InstrList[M->SuffixIdx]; MachineBasicBlock::iterator EndIt = Mapper.InstrList[M->SuffixIdx + StringLen - 1]; - CallOverhead += TII.getOutliningCallOverhead(StartIt, EndIt); + + // Get the overhead for calling a function for this sequence and any + // target-specified data for how to construct the call. + std::pair<size_t, unsigned> CallOverheadPair = + TII.getOutliningCallOverhead(StartIt, EndIt); + CallOverhead += CallOverheadPair.first; + CandidatesForRepeatedSeq.emplace_back(M->SuffixIdx, StringLen, FnIdx, + CallOverheadPair.second); + CandidateClass.emplace_back(std::make_pair(StartIt, EndIt)); + + // Never visit this leaf again. + M->IsInTree = false; } } - // Figure out how many instructions it'll take to construct an outlined - // function frame for this sequence. - MachineBasicBlock::iterator StartIt = Mapper.InstrList[Leaf->SuffixIdx]; - MachineBasicBlock::iterator EndIt = - Mapper.InstrList[Leaf->SuffixIdx + StringLen - 1]; - FrameOverhead = TII.getOutliningFrameOverhead(StartIt, EndIt); + std::pair<size_t, unsigned> FrameOverheadPair = + TII.getOutliningFrameOverhead(CandidateClass); + size_t FrameOverhead = FrameOverheadPair.first; size_t OutliningCost = CallOverhead + FrameOverhead + SequenceOverhead; size_t NotOutliningCost = SequenceOverhead * Parent.OccurrenceCount; @@ -876,17 +896,11 @@ MachineOutliner::findCandidates(SuffixTree &ST, const TargetInstrInfo &TII, if (StringLen > MaxLen) MaxLen = StringLen; - unsigned OccurrenceCount = 0; - for (auto &ChildPair : Parent.Children) { - SuffixTreeNode *M = ChildPair.second; - - // Is it a leaf? If so, we have an occurrence of this candidate. - if (M && M->IsInTree && M->isLeaf()) { - OccurrenceCount++; - CandidateList.emplace_back(M->SuffixIdx, StringLen, FnIdx); - CandidateList.back().Benefit = Benefit; - M->IsInTree = false; - } + // At this point, the candidate class is seen as beneficial. Set their + // benefit values and save them in the candidate list. + for (Candidate &C : CandidatesForRepeatedSeq) { + C.Benefit = Benefit; + CandidateList.push_back(C); } // Save the function for the new candidate sequence. @@ -894,8 +908,9 @@ MachineOutliner::findCandidates(SuffixTree &ST, const TargetInstrInfo &TII, for (unsigned i = Leaf->SuffixIdx; i < Leaf->SuffixIdx + StringLen; i++) CandidateSequence.push_back(ST.Str[i]); - FunctionList.emplace_back(FnIdx, OccurrenceCount, CandidateSequence, - Benefit, false); + FunctionList.emplace_back(FnIdx, CandidatesForRepeatedSeq.size(), + CandidateSequence, Benefit, + FrameOverheadPair.second); // Move to the next function. FnIdx++; @@ -996,7 +1011,8 @@ void MachineOutliner::pruneOverlaps(std::vector<Candidate> &CandidateList, MachineBasicBlock::iterator StartIt = Mapper.InstrList[C2.StartIdx]; MachineBasicBlock::iterator EndIt = Mapper.InstrList[C2.StartIdx + C2.Len - 1]; - F2.Benefit += TII.getOutliningCallOverhead(StartIt, EndIt); + + F2.Benefit += TII.getOutliningCallOverhead(StartIt, EndIt).first; // Add back one instance of the sequence. if (F2.Sequence.size() > F2.Benefit) @@ -1022,7 +1038,8 @@ void MachineOutliner::pruneOverlaps(std::vector<Candidate> &CandidateList, MachineBasicBlock::iterator StartIt = Mapper.InstrList[C1.StartIdx]; MachineBasicBlock::iterator EndIt = Mapper.InstrList[C1.StartIdx + C1.Len - 1]; - F2.Benefit += TII.getOutliningCallOverhead(StartIt, EndIt); + + F1.Benefit += TII.getOutliningCallOverhead(StartIt, EndIt).first; // Add back one instance of the sequence. if (F1.Sequence.size() > F1.Benefit) @@ -1056,10 +1073,6 @@ MachineOutliner::buildCandidateList(std::vector<Candidate> &CandidateList, MaxCandidateLen = findCandidates(ST, TII, Mapper, CandidateList, FunctionList); - for (auto &OF : FunctionList) - OF.IsTailCall = - Mapper.IntegerInstructionMap[OF.Sequence.back()]->isTerminator(); - // Sort the candidates in decending order. This will simplify the outlining // process when we have to remove the candidates from the mapping by // allowing us to cut them out without keeping track of an offset. @@ -1102,7 +1115,7 @@ MachineOutliner::createOutlinedFunction(Module &M, const OutlinedFunction &OF, // Insert the new function into the module. MF.insert(MF.begin(), &MBB); - TII.insertOutlinerPrologue(MBB, MF, OF.IsTailCall); + TII.insertOutlinerPrologue(MBB, MF, OF.FrameClass); // Copy over the instructions for the function using the integer mappings in // its sequence. @@ -1117,7 +1130,7 @@ MachineOutliner::createOutlinedFunction(Module &M, const OutlinedFunction &OF, MBB.insert(MBB.end(), NewMI); } - TII.insertOutlinerEpilogue(MBB, MF, OF.IsTailCall); + TII.insertOutlinerEpilogue(MBB, MF, OF.FrameClass); return &MF; } @@ -1166,7 +1179,7 @@ bool MachineOutliner::outline(Module &M, const TargetInstrInfo &TII = *STI.getInstrInfo(); // Insert a call to the new function and erase the old sequence. - TII.insertOutlinedCall(M, *MBB, StartIt, *MF, OF.IsTailCall); + TII.insertOutlinedCall(M, *MBB, StartIt, *MF, C.CallClass); StartIt = Mapper.InstrList[C.StartIdx]; MBB->erase(StartIt, EndIt); diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 9afd05f99e9..8656b125fdd 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -4432,27 +4432,34 @@ AArch64InstrInfo::getSerializableMachineMemOperandTargetFlags() const { return makeArrayRef(TargetFlags); } -size_t AArch64InstrInfo::getOutliningCallOverhead( +// Constants defining how certain sequences should be outlined. +const unsigned MachineOutlinerDefaultFn = 0; +const unsigned MachineOutlinerTailCallFn = 1; + +std::pair<size_t, unsigned> AArch64InstrInfo::getOutliningCallOverhead( MachineBasicBlock::iterator &StartIt, MachineBasicBlock::iterator &EndIt) const { // Is this a tail-call? - if (EndIt->isTerminator()) - return 1; // Yes, so we don't need to save/restore LR. + if (EndIt->isTerminator()) { + // Yes, so we only have to emit a call. Return a cost of 1 + signify that + // this candidate should be tail-called. + return std::make_pair(1, MachineOutlinerTailCallFn); + } // No, so save + restore LR. - return 3; + return std::make_pair(3, MachineOutlinerDefaultFn); } -size_t AArch64InstrInfo::getOutliningFrameOverhead( - MachineBasicBlock::iterator &StartIt, - MachineBasicBlock::iterator &EndIt) const { +std::pair<size_t, unsigned> AArch64InstrInfo::getOutliningFrameOverhead( + std::vector<std::pair<MachineBasicBlock::iterator, + MachineBasicBlock::iterator>> &CandidateClass) const { - // Is this a tail-call? - if (EndIt->isTerminator()) - return 0; // Yes, so we already have a return. + // Is the last instruction in this class a terminator? + if (CandidateClass[0].second->isTerminator()) + return std::make_pair(0, MachineOutlinerTailCallFn); // No, so we have to add a return to the end. - return 1; + return std::make_pair(1, MachineOutlinerDefaultFn); } bool AArch64InstrInfo::isFunctionSafeToOutlineFrom(MachineFunction &MF) const { @@ -4568,10 +4575,10 @@ void AArch64InstrInfo::fixupPostOutline(MachineBasicBlock &MBB) const { void AArch64InstrInfo::insertOutlinerEpilogue(MachineBasicBlock &MBB, MachineFunction &MF, - bool IsTailCall) const { + unsigned FrameClass) const { // If this is a tail call outlined function, then there's already a return. - if (IsTailCall) + if (FrameClass == MachineOutlinerTailCallFn) return; // It's not a tail call, so we have to insert the return ourselves. @@ -4585,18 +4592,17 @@ void AArch64InstrInfo::insertOutlinerEpilogue(MachineBasicBlock &MBB, void AArch64InstrInfo::insertOutlinerPrologue(MachineBasicBlock &MBB, MachineFunction &MF, - bool IsTailCall) const {} + unsigned FrameClass) const {} MachineBasicBlock::iterator AArch64InstrInfo::insertOutlinedCall( Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It, - MachineFunction &MF, bool IsTailCall) const { + MachineFunction &MF, unsigned CallClass) const { // Are we tail calling? - if (IsTailCall) { + if (CallClass == MachineOutlinerTailCallFn) { // If yes, then we can just branch to the label. - It = MBB.insert(It, - BuildMI(MF, DebugLoc(), get(AArch64::B)) - .addGlobalAddress(M.getNamedValue(MF.getName()))); + It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(AArch64::B)) + .addGlobalAddress(M.getNamedValue(MF.getName()))); return It; } @@ -4611,9 +4617,8 @@ MachineBasicBlock::iterator AArch64InstrInfo::insertOutlinedCall( It++; // Insert the call. - It = MBB.insert(It, - BuildMI(MF, DebugLoc(), get(AArch64::BL)) - .addGlobalAddress(M.getNamedValue(MF.getName()))); + It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(AArch64::BL)) + .addGlobalAddress(M.getNamedValue(MF.getName()))); It++; diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.h b/llvm/lib/Target/AArch64/AArch64InstrInfo.h index 076a32f911f..faf832657fd 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h @@ -136,37 +136,88 @@ public: default: llvm_unreachable("Opcode has no flag setting equivalent!"); // 32-bit cases: - case AArch64::ADDWri: Is64Bit = false; return AArch64::ADDSWri; - case AArch64::ADDWrr: Is64Bit = false; return AArch64::ADDSWrr; - case AArch64::ADDWrs: Is64Bit = false; return AArch64::ADDSWrs; - case AArch64::ADDWrx: Is64Bit = false; return AArch64::ADDSWrx; - case AArch64::ANDWri: Is64Bit = false; return AArch64::ANDSWri; - case AArch64::ANDWrr: Is64Bit = false; return AArch64::ANDSWrr; - case AArch64::ANDWrs: Is64Bit = false; return AArch64::ANDSWrs; - case AArch64::BICWrr: Is64Bit = false; return AArch64::BICSWrr; - case AArch64::BICWrs: Is64Bit = false; return AArch64::BICSWrs; - case AArch64::SUBWri: Is64Bit = false; return AArch64::SUBSWri; - case AArch64::SUBWrr: Is64Bit = false; return AArch64::SUBSWrr; - case AArch64::SUBWrs: Is64Bit = false; return AArch64::SUBSWrs; - case AArch64::SUBWrx: Is64Bit = false; return AArch64::SUBSWrx; + case AArch64::ADDWri: + Is64Bit = false; + return AArch64::ADDSWri; + case AArch64::ADDWrr: + Is64Bit = false; + return AArch64::ADDSWrr; + case AArch64::ADDWrs: + Is64Bit = false; + return AArch64::ADDSWrs; + case AArch64::ADDWrx: + Is64Bit = false; + return AArch64::ADDSWrx; + case AArch64::ANDWri: + Is64Bit = false; + return AArch64::ANDSWri; + case AArch64::ANDWrr: + Is64Bit = false; + return AArch64::ANDSWrr; + case AArch64::ANDWrs: + Is64Bit = false; + return AArch64::ANDSWrs; + case AArch64::BICWrr: + Is64Bit = false; + return AArch64::BICSWrr; + case AArch64::BICWrs: + Is64Bit = false; + return AArch64::BICSWrs; + case AArch64::SUBWri: + Is64Bit = false; + return AArch64::SUBSWri; + case AArch64::SUBWrr: + Is64Bit = false; + return AArch64::SUBSWrr; + case AArch64::SUBWrs: + Is64Bit = false; + return AArch64::SUBSWrs; + case AArch64::SUBWrx: + Is64Bit = false; + return AArch64::SUBSWrx; // 64-bit cases: - case AArch64::ADDXri: Is64Bit = true; return AArch64::ADDSXri; - case AArch64::ADDXrr: Is64Bit = true; return AArch64::ADDSXrr; - case AArch64::ADDXrs: Is64Bit = true; return AArch64::ADDSXrs; - case AArch64::ADDXrx: Is64Bit = true; return AArch64::ADDSXrx; - case AArch64::ANDXri: Is64Bit = true; return AArch64::ANDSXri; - case AArch64::ANDXrr: Is64Bit = true; return AArch64::ANDSXrr; - case AArch64::ANDXrs: Is64Bit = true; return AArch64::ANDSXrs; - case AArch64::BICXrr: Is64Bit = true; return AArch64::BICSXrr; - case AArch64::BICXrs: Is64Bit = true; return AArch64::BICSXrs; - case AArch64::SUBXri: Is64Bit = true; return AArch64::SUBSXri; - case AArch64::SUBXrr: Is64Bit = true; return AArch64::SUBSXrr; - case AArch64::SUBXrs: Is64Bit = true; return AArch64::SUBSXrs; - case AArch64::SUBXrx: Is64Bit = true; return AArch64::SUBSXrx; + case AArch64::ADDXri: + Is64Bit = true; + return AArch64::ADDSXri; + case AArch64::ADDXrr: + Is64Bit = true; + return AArch64::ADDSXrr; + case AArch64::ADDXrs: + Is64Bit = true; + return AArch64::ADDSXrs; + case AArch64::ADDXrx: + Is64Bit = true; + return AArch64::ADDSXrx; + case AArch64::ANDXri: + Is64Bit = true; + return AArch64::ANDSXri; + case AArch64::ANDXrr: + Is64Bit = true; + return AArch64::ANDSXrr; + case AArch64::ANDXrs: + Is64Bit = true; + return AArch64::ANDSXrs; + case AArch64::BICXrr: + Is64Bit = true; + return AArch64::BICSXrr; + case AArch64::BICXrs: + Is64Bit = true; + return AArch64::BICSXrs; + case AArch64::SUBXri: + Is64Bit = true; + return AArch64::SUBSXri; + case AArch64::SUBXrr: + Is64Bit = true; + return AArch64::SUBSXrr; + case AArch64::SUBXrs: + Is64Bit = true; + return AArch64::SUBSXrs; + case AArch64::SUBXrx: + Is64Bit = true; + return AArch64::SUBSXrx; } } - /// Return true if this is a load/store that can be potentially paired/merged. bool isCandidateToMergeOrPair(MachineInstr &MI) const; @@ -271,9 +322,9 @@ public: /// Return true when there is potentially a faster code sequence /// for an instruction chain ending in ``Root``. All potential patterns are /// listed in the ``Patterns`` array. - bool getMachineCombinerPatterns(MachineInstr &Root, - SmallVectorImpl<MachineCombinerPattern> &Patterns) - const override; + bool getMachineCombinerPatterns( + MachineInstr &Root, + SmallVectorImpl<MachineCombinerPattern> &Patterns) const override; /// Return true when Inst is associative and commutative so that it can be /// reassociated. bool isAssociativeAndCommutative(const MachineInstr &Inst) const override; @@ -299,28 +350,28 @@ public: getSerializableMachineMemOperandTargetFlags() const override; bool isFunctionSafeToOutlineFrom(MachineFunction &MF) const override; - size_t getOutliningCallOverhead(MachineBasicBlock::iterator &StartIt, - MachineBasicBlock::iterator &EndIt) const override; - size_t getOutliningFrameOverhead(MachineBasicBlock::iterator &StartIt, - MachineBasicBlock::iterator &EndIt) const override; + std::pair<size_t, unsigned> + getOutliningCallOverhead(MachineBasicBlock::iterator &StartIt, + MachineBasicBlock::iterator &EndIt) const override; + std::pair<size_t, unsigned> getOutliningFrameOverhead( + std::vector< + std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>> + &CandidateClass) const override; AArch64GenInstrInfo::MachineOutlinerInstrType getOutliningType(MachineInstr &MI) const override; - void insertOutlinerEpilogue(MachineBasicBlock &MBB, - MachineFunction &MF, - bool IsTailCall) const override; - void insertOutlinerPrologue(MachineBasicBlock &MBB, - MachineFunction &MF, - bool isTailCall) const override; + void insertOutlinerEpilogue(MachineBasicBlock &MBB, MachineFunction &MF, + unsigned FrameClass) const override; + void insertOutlinerPrologue(MachineBasicBlock &MBB, MachineFunction &MF, + unsigned FrameClass) const override; MachineBasicBlock::iterator insertOutlinedCall(Module &M, MachineBasicBlock &MBB, - MachineBasicBlock::iterator &It, - MachineFunction &MF, - bool IsTailCall) const override; + MachineBasicBlock::iterator &It, MachineFunction &MF, + unsigned CallClass) const override; /// Returns true if the instruction has a shift by immediate that can be /// executed in one cycle less. bool isFalkorShiftExtFast(const MachineInstr &MI) const; -private: +private: /// \brief Sets the offsets on outlined instructions in \p MBB which use SP /// so that they will be valid post-outlining. /// @@ -348,8 +399,8 @@ void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, /// FP. Return false if the offset could not be handled directly in MI, and /// return the left-over portion by reference. bool rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, - unsigned FrameReg, int &Offset, - const AArch64InstrInfo *TII); + unsigned FrameReg, int &Offset, + const AArch64InstrInfo *TII); /// \brief Use to report the frame offset status in isAArch64FrameOffsetLegal. enum AArch64FrameOffsetStatus { @@ -373,9 +424,9 @@ enum AArch64FrameOffsetStatus { /// (possibly with @p OutUnscaledOp if OutUseUnscaledOp is true) and that /// is a legal offset. int isAArch64FrameOffsetLegal(const MachineInstr &MI, int &Offset, - bool *OutUseUnscaledOp = nullptr, - unsigned *OutUnscaledOp = nullptr, - int *EmittableOffset = nullptr); + bool *OutUseUnscaledOp = nullptr, + unsigned *OutUnscaledOp = nullptr, + int *EmittableOffset = nullptr); static inline bool isUncondBranchOpcode(int Opc) { return Opc == AArch64::B; } @@ -396,7 +447,9 @@ static inline bool isCondBranchOpcode(int Opc) { } } -static inline bool isIndirectBranchOpcode(int Opc) { return Opc == AArch64::BR; } +static inline bool isIndirectBranchOpcode(int Opc) { + return Opc == AArch64::BR; +} } // end namespace llvm diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index 8eb1536790d..ac1c0c9357d 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -10537,22 +10537,31 @@ char LDTLSCleanup::ID = 0; FunctionPass* llvm::createCleanupLocalDynamicTLSPass() { return new LDTLSCleanup(); } -size_t X86InstrInfo::getOutliningCallOverhead( -MachineBasicBlock::iterator &StartIt, -MachineBasicBlock::iterator &EndIt) const { - // We just have to emit a call, so return 1. - return 1; +// Constants defining how certain sequences should be outlined. +const unsigned MachineOutlinerDefaultFn = 0; +const unsigned MachineOutlinerTailCallFn = 1; + +std::pair<size_t, unsigned> X86InstrInfo::getOutliningCallOverhead( + MachineBasicBlock::iterator &StartIt, + MachineBasicBlock::iterator &EndIt) const { + + // Is this a tail call? If it is, make note of it. + if (EndIt->isTerminator()) + return std::make_pair(1, MachineOutlinerTailCallFn); + + return std::make_pair(1, MachineOutlinerDefaultFn); } -size_t X86InstrInfo::getOutliningFrameOverhead( -MachineBasicBlock::iterator &StartIt, -MachineBasicBlock::iterator &EndIt) const { +std::pair<size_t, unsigned> X86InstrInfo::getOutliningFrameOverhead( + std::vector<std::pair<MachineBasicBlock::iterator, + MachineBasicBlock::iterator>> &CandidateClass) const { // Is this a tail-call? - if (EndIt->isTerminator()) - return 0; // Yes, so we already have a return. + // Is the last instruction in this class a terminator? + if (CandidateClass[0].second->isTerminator()) + return std::make_pair(0, MachineOutlinerTailCallFn); // No, so we have to add a return to the end. - return 1; + return std::make_pair(1, MachineOutlinerDefaultFn); } bool X86InstrInfo::isFunctionSafeToOutlineFrom(MachineFunction &MF) const { @@ -10616,10 +10625,10 @@ X86InstrInfo::getOutliningType(MachineInstr &MI) const { void X86InstrInfo::insertOutlinerEpilogue(MachineBasicBlock &MBB, MachineFunction &MF, - bool IsTailCall) const { + unsigned FrameClass) const { // If we're a tail call, we already have a return, so don't do anything. - if (IsTailCall) + if (FrameClass == MachineOutlinerTailCallFn) return; // We're a normal call, so our sequence doesn't have a return instruction. @@ -10630,15 +10639,15 @@ void X86InstrInfo::insertOutlinerEpilogue(MachineBasicBlock &MBB, void X86InstrInfo::insertOutlinerPrologue(MachineBasicBlock &MBB, MachineFunction &MF, - bool IsTailCall) const {} + unsigned FrameClass) const {} MachineBasicBlock::iterator X86InstrInfo::insertOutlinedCall(Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It, MachineFunction &MF, - bool IsTailCall) const { + unsigned CallClass) const { // Is it a tail call? - if (IsTailCall) { + if (CallClass == MachineOutlinerTailCallFn) { // Yes, just insert a JMP. It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(X86::JMP_1)) diff --git a/llvm/lib/Target/X86/X86InstrInfo.h b/llvm/lib/Target/X86/X86InstrInfo.h index 38caf04f7f8..00684f52cb3 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.h +++ b/llvm/lib/Target/X86/X86InstrInfo.h @@ -24,13 +24,13 @@ #include "X86GenInstrInfo.inc" namespace llvm { - class MachineInstrBuilder; - class X86RegisterInfo; - class X86Subtarget; +class MachineInstrBuilder; +class X86RegisterInfo; +class X86Subtarget; namespace X86 { - // X86 specific condition code. These correspond to X86_*_COND in - // X86InstrInfo.td. They must be kept in synch. +// X86 specific condition code. These correspond to X86_*_COND in +// X86InstrInfo.td. They must be kept in synch. enum CondCode { COND_A = 0, COND_AE = 1, @@ -83,18 +83,17 @@ CondCode getCondFromCMovOpc(unsigned Opc); /// GetOppositeBranchCondition - Return the inverse of the specified cond, /// e.g. turning COND_E to COND_NE. CondCode GetOppositeBranchCondition(CondCode CC); -} // end namespace X86; - +} // namespace X86 /// isGlobalStubReference - Return true if the specified TargetFlag operand is /// a reference to a stub for a global, not the global itself. inline static bool isGlobalStubReference(unsigned char TargetFlag) { switch (TargetFlag) { - case X86II::MO_DLLIMPORT: // dllimport stub. - case X86II::MO_GOTPCREL: // rip-relative GOT reference. - case X86II::MO_GOT: // normal GOT reference. - case X86II::MO_DARWIN_NONLAZY_PIC_BASE: // Normal $non_lazy_ptr ref. - case X86II::MO_DARWIN_NONLAZY: // Normal $non_lazy_ptr ref. + case X86II::MO_DLLIMPORT: // dllimport stub. + case X86II::MO_GOTPCREL: // rip-relative GOT reference. + case X86II::MO_GOT: // normal GOT reference. + case X86II::MO_DARWIN_NONLAZY_PIC_BASE: // Normal $non_lazy_ptr ref. + case X86II::MO_DARWIN_NONLAZY: // Normal $non_lazy_ptr ref. return true; default: return false; @@ -106,11 +105,11 @@ inline static bool isGlobalStubReference(unsigned char TargetFlag) { /// is true, the addressing mode has the PIC base register added in (e.g. EBX). inline static bool isGlobalRelativeToPICBase(unsigned char TargetFlag) { switch (TargetFlag) { - case X86II::MO_GOTOFF: // isPICStyleGOT: local global. - case X86II::MO_GOT: // isPICStyleGOT: other global. - case X86II::MO_PIC_BASE_OFFSET: // Darwin local global. - case X86II::MO_DARWIN_NONLAZY_PIC_BASE: // Darwin/32 external global. - case X86II::MO_TLVP: // ??? Pretty sure.. + case X86II::MO_GOTOFF: // isPICStyleGOT: local global. + case X86II::MO_GOT: // isPICStyleGOT: other global. + case X86II::MO_PIC_BASE_OFFSET: // Darwin local global. + case X86II::MO_DARWIN_NONLAZY_PIC_BASE: // Darwin/32 external global. + case X86II::MO_TLVP: // ??? Pretty sure.. return true; default: return false; @@ -118,9 +117,8 @@ inline static bool isGlobalRelativeToPICBase(unsigned char TargetFlag) { } inline static bool isScale(const MachineOperand &MO) { - return MO.isImm() && - (MO.getImm() == 1 || MO.getImm() == 2 || - MO.getImm() == 4 || MO.getImm() == 8); + return MO.isImm() && (MO.getImm() == 1 || MO.getImm() == 2 || + MO.getImm() == 4 || MO.getImm() == 8); } inline static bool isLeaMem(const MachineInstr &MI, unsigned Op) { @@ -150,8 +148,8 @@ class X86InstrInfo final : public X86GenInstrInfo { /// RegOp2MemOpTable3Addr, RegOp2MemOpTable0, RegOp2MemOpTable1, /// RegOp2MemOpTable2, RegOp2MemOpTable3 - Load / store folding opcode maps. /// - typedef DenseMap<unsigned, - std::pair<uint16_t, uint16_t> > RegOp2MemOpTableType; + typedef DenseMap<unsigned, std::pair<uint16_t, uint16_t>> + RegOp2MemOpTableType; RegOp2MemOpTableType RegOp2MemOpTable2Addr; RegOp2MemOpTableType RegOp2MemOpTable0; RegOp2MemOpTableType RegOp2MemOpTable1; @@ -161,13 +159,13 @@ class X86InstrInfo final : public X86GenInstrInfo { /// MemOp2RegOpTable - Load / store unfolding opcode map. /// - typedef DenseMap<unsigned, - std::pair<uint16_t, uint16_t> > MemOp2RegOpTableType; + typedef DenseMap<unsigned, std::pair<uint16_t, uint16_t>> + MemOp2RegOpTableType; MemOp2RegOpTableType MemOp2RegOpTable; static void AddTableEntry(RegOp2MemOpTableType &R2MTable, - MemOp2RegOpTableType &M2RTable, - uint16_t RegOp, uint16_t MemOp, uint16_t Flags); + MemOp2RegOpTableType &M2RTable, uint16_t RegOp, + uint16_t MemOp, uint16_t Flags); virtual void anchor(); @@ -216,9 +214,8 @@ public: /// true, then it's expected the pre-extension value is available as a subreg /// of the result register. This also returns the sub-register index in /// SubIdx. - bool isCoalescableExtInstr(const MachineInstr &MI, - unsigned &SrcReg, unsigned &DstReg, - unsigned &SubIdx) const override; + bool isCoalescableExtInstr(const MachineInstr &MI, unsigned &SrcReg, + unsigned &DstReg, unsigned &SubIdx) const override; unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override; @@ -253,8 +250,8 @@ public: /// operand to the LEA instruction. bool classifyLEAReg(MachineInstr &MI, const MachineOperand &Src, unsigned LEAOpcode, bool AllowSP, unsigned &NewSrc, - bool &isKill, bool &isUndef, - MachineOperand &ImplicitOp, LiveVariables *LV) const; + bool &isKill, bool &isUndef, MachineOperand &ImplicitOp, + LiveVariables *LV) const; /// convertToThreeAddress - This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target @@ -312,8 +309,7 @@ public: /// FMA213 #1, #2, #3 /// results into instruction with adjusted opcode: /// FMA231 #3, #2, #1 - bool findFMA3CommutedOpIndices(const MachineInstr &MI, - unsigned &SrcOpIdx1, + bool findFMA3CommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2, const X86InstrFMA3Group &FMA3Group) const; @@ -332,10 +328,10 @@ public: /// FMA213 #1, #2, #3 /// results into instruction with adjusted opcode: /// FMA231 #3, #2, #1 - unsigned getFMA3OpcodeToCommuteOperands(const MachineInstr &MI, - unsigned SrcOpIdx1, - unsigned SrcOpIdx2, - const X86InstrFMA3Group &FMA3Group) const; + unsigned + getFMA3OpcodeToCommuteOperands(const MachineInstr &MI, unsigned SrcOpIdx1, + unsigned SrcOpIdx2, + const X86InstrFMA3Group &FMA3Group) const; // Branch analysis. bool isUnpredicatedTerminator(const MachineInstr &MI) const override; @@ -364,8 +360,8 @@ public: MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded = nullptr) const override; - bool canInsertSelect(const MachineBasicBlock&, ArrayRef<MachineOperand> Cond, - unsigned, unsigned, int&, int&, int&) const override; + bool canInsertSelect(const MachineBasicBlock &, ArrayRef<MachineOperand> Cond, + unsigned, unsigned, int &, int &, int &) const override; void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, unsigned DstReg, ArrayRef<MachineOperand> Cond, unsigned TrueReg, @@ -374,8 +370,8 @@ public: const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const override; void storeRegToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned SrcReg, bool isKill, int FrameIndex, + MachineBasicBlock::iterator MI, unsigned SrcReg, + bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override; @@ -384,12 +380,11 @@ public: const TargetRegisterClass *RC, MachineInstr::mmo_iterator MMOBegin, MachineInstr::mmo_iterator MMOEnd, - SmallVectorImpl<MachineInstr*> &NewMIs) const; + SmallVectorImpl<MachineInstr *> &NewMIs) const; void loadRegFromStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned DestReg, int FrameIndex, - const TargetRegisterClass *RC, + MachineBasicBlock::iterator MI, unsigned DestReg, + int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override; void loadRegFromAddr(MachineFunction &MF, unsigned DestReg, @@ -397,7 +392,7 @@ public: const TargetRegisterClass *RC, MachineInstr::mmo_iterator MMOBegin, MachineInstr::mmo_iterator MMOEnd, - SmallVectorImpl<MachineInstr*> &NewMIs) const; + SmallVectorImpl<MachineInstr *> &NewMIs) const; bool expandPostRAPseudo(MachineInstr &MI) const override; @@ -434,7 +429,7 @@ public: SmallVectorImpl<MachineInstr *> &NewMIs) const override; bool unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N, - SmallVectorImpl<SDNode*> &NewNodes) const override; + SmallVectorImpl<SDNode *> &NewNodes) const override; /// getOpcodeAfterMemoryUnfold - Returns the opcode of the would be new /// instruction after load / store are unfolded from an instruction of the @@ -442,9 +437,9 @@ public: /// possible. If LoadRegIndex is non-null, it is filled in with the operand /// index of the operand which will hold the register holding the loaded /// value. - unsigned getOpcodeAfterMemoryUnfold(unsigned Opc, - bool UnfoldLoad, bool UnfoldStore, - unsigned *LoadRegIndex = nullptr) const override; + unsigned + getOpcodeAfterMemoryUnfold(unsigned Opc, bool UnfoldLoad, bool UnfoldStore, + unsigned *LoadRegIndex = nullptr) const override; /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler /// to determine if two loads are loading from the same base address. It @@ -455,15 +450,15 @@ public: int64_t &Offset2) const override; /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to - /// determine (in conjunction with areLoadsFromSameBasePtr) if two loads should - /// be scheduled togther. On some targets if two loads are loading from + /// determine (in conjunction with areLoadsFromSameBasePtr) if two loads + /// should be scheduled togther. On some targets if two loads are loading from /// addresses in the same cache line, it's better if they are scheduled /// together. This function takes two integers that represent the load offsets /// from the common base address. It returns true if it decides it's desirable /// to schedule the two loads together. "NumLoads" is the number of loads that /// have already been scheduled after Load1. - bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, - int64_t Offset1, int64_t Offset2, + bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, int64_t Offset1, + int64_t Offset2, unsigned NumLoads) const override; void getNoop(MCInst &NopInst) const override; @@ -520,9 +515,7 @@ public: const MachineInstr &UseMI, unsigned UseIdx) const override; - bool useMachineCombiner() const override { - return true; - } + bool useMachineCombiner() const override { return true; } bool isAssociativeAndCommutative(const MachineInstr &Inst) const override; @@ -566,30 +559,31 @@ public: ArrayRef<std::pair<unsigned, const char *>> getSerializableDirectMachineOperandTargetFlags() const override; - size_t getOutliningCallOverhead(MachineBasicBlock::iterator &StartIt, - MachineBasicBlock::iterator &EndIt) const override; - - size_t getOutliningFrameOverhead(MachineBasicBlock::iterator &StartIt, - MachineBasicBlock::iterator &EndIt) const override; + std::pair<size_t, unsigned> + getOutliningCallOverhead(MachineBasicBlock::iterator &StartIt, + MachineBasicBlock::iterator &EndIt) const override; + + std::pair<size_t, unsigned> getOutliningFrameOverhead( + std::vector< + std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>> + &CandidateClass) const override; bool isFunctionSafeToOutlineFrom(MachineFunction &MF) const override; llvm::X86GenInstrInfo::MachineOutlinerInstrType getOutliningType(MachineInstr &MI) const override; - void insertOutlinerEpilogue(MachineBasicBlock &MBB, - MachineFunction &MF, - bool IsTailCall) const override; + void insertOutlinerEpilogue(MachineBasicBlock &MBB, MachineFunction &MF, + unsigned FrameClass) const override; - void insertOutlinerPrologue(MachineBasicBlock &MBB, - MachineFunction &MF, - bool isTailCall) const override; + void insertOutlinerPrologue(MachineBasicBlock &MBB, MachineFunction &MF, + unsigned FrameClass) const override; MachineBasicBlock::iterator insertOutlinedCall(Module &M, MachineBasicBlock &MBB, - MachineBasicBlock::iterator &It, - MachineFunction &MF, - bool IsTailCall) const override; + MachineBasicBlock::iterator &It, MachineFunction &MF, + unsigned CallClass) const override; + protected: /// Commutes the operands in the given instruction by changing the operands /// order and/or changing the instruction's opcode and/or the immediate value @@ -645,6 +639,6 @@ private: unsigned &SrcOpIdx2) const; }; -} // End llvm namespace +} // namespace llvm #endif |