/// shouldn't actually impact the outlining result.
enum InstrType { Legal, LegalTerminator, Illegal, Invisible };
-/// Describes the number of instructions that it will take to call and
-/// construct a frame for a given outlining candidate.
-struct TargetCostInfo {
- /// Represents the size of a sequence in bytes. (Some instructions vary
- /// widely in size, so just counting the instructions isn't very useful.)
- unsigned SequenceSize;
-
- /// Number of instructions to construct an outlined function frame
- /// for this candidate.
- unsigned FrameOverhead;
-
- /// Represents the specific instructions that must be emitted to
- /// construct a frame for this candidate's outlined function.
- unsigned FrameConstructionID;
-
- TargetCostInfo() {}
- TargetCostInfo(unsigned SequenceSize, unsigned FrameOverhead,
- unsigned FrameConstructionID)
- : SequenceSize(SequenceSize), FrameOverhead(FrameOverhead),
- FrameConstructionID(FrameConstructionID) {}
-};
-
/// An individual sequence of instructions to be replaced with a call to
/// an outlined function.
struct Candidate {
/// function.
std::vector<unsigned> Sequence;
- /// Contains all target-specific information for this \p OutlinedFunction.
- TargetCostInfo TCI;
+ /// Represents the size of a sequence in bytes. (Some instructions vary
+ /// widely in size, so just counting the instructions isn't very useful.)
+ unsigned SequenceSize;
+
+ /// Target-defined overhead of constructing a frame for this function.
+ unsigned FrameOverhead;
+
+ /// Target-defined identifier for constructing a frame for this function.
+ unsigned FrameConstructionID;
/// Return the number of candidates for this \p OutlinedFunction.
unsigned getOccurrenceCount() { return OccurrenceCount; }
unsigned CallOverhead = 0;
for (std::shared_ptr<Candidate> &C : Candidates)
CallOverhead += C->getCallOverhead();
- return CallOverhead + TCI.SequenceSize + TCI.FrameOverhead;
+ return CallOverhead + SequenceSize + FrameOverhead;
}
/// Return the size in bytes of the unoutlined sequences.
- unsigned getNotOutlinedCost() { return OccurrenceCount * TCI.SequenceSize; }
+ unsigned getNotOutlinedCost() { return OccurrenceCount * SequenceSize; }
/// Return the number of instructions that would be saved by outlining
/// this function.
: NotOutlinedCost - OutlinedCost;
}
- OutlinedFunction(unsigned Name, std::vector<Candidate> &Cands,
- const std::vector<unsigned> &Sequence, TargetCostInfo &TCI)
- : Name(Name), Sequence(Sequence), TCI(TCI) {
+ OutlinedFunction(std::vector<Candidate> &Cands,
+ unsigned SequenceSize, unsigned FrameOverhead,
+ unsigned FrameConstructionID)
+ : SequenceSize(SequenceSize), FrameOverhead(FrameOverhead),
+ FrameConstructionID(FrameConstructionID) {
OccurrenceCount = Cands.size();
for (Candidate &C : Cands)
Candidates.push_back(std::make_shared<outliner::Candidate>(C));
return false;
}
- /// Returns a \p outliner::TargetCostInfo struct containing target-specific
+ /// Returns a \p outliner::OutlinedFunction struct containing target-specific
/// information for a set of outlining candidates.
- virtual outliner::TargetCostInfo getOutliningCandidateInfo(
+ virtual outliner::OutlinedFunction getOutliningCandidateInfo(
std::vector<outliner::Candidate> &RepeatedSequenceLocs) const {
llvm_unreachable(
"Target didn't implement TargetInstrInfo::getOutliningCandidateInfo!");
}
/// Insert a custom frame for outlined functions.
- virtual void buildOutlinedFrame(MachineBasicBlock &MBB,
- MachineFunction &MF,
- const outliner::TargetCostInfo &TCI) const {
+ virtual void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF,
+ const outliner::OutlinedFunction &OF) const {
llvm_unreachable(
"Target didn't implement TargetInstrInfo::buildOutlinedFrame!");
}
// We've found something we might want to outline.
// Create an OutlinedFunction to store it and check if it'd be beneficial
// to outline.
- TargetCostInfo TCI =
- TII.getOutliningCandidateInfo(CandidatesForRepeatedSeq);
+ OutlinedFunction OF = TII.getOutliningCandidateInfo(CandidatesForRepeatedSeq);
std::vector<unsigned> Seq;
for (unsigned i = Leaf->SuffixIdx; i < Leaf->SuffixIdx + StringLen; i++)
Seq.push_back(ST.Str[i]);
- OutlinedFunction OF(FunctionList.size(), CandidatesForRepeatedSeq, Seq,
- TCI);
+ OF.Sequence = Seq;
+ OF.Name = FunctionList.size();
// Is it better to outline this candidate than not?
if (OF.getBenefit() < 1) {
MBB.insert(MBB.end(), NewMI);
}
- TII.buildOutlinedFrame(MBB, MF, OF.TCI);
+ TII.buildOutlinedFrame(MBB, MF, OF);
// If there's a DISubprogram associated with this outlined function, then
// emit debug info for the outlined function.
HasCalls = 0x4
};
-outliner::TargetCostInfo
+outliner::OutlinedFunction
AArch64InstrInfo::getOutliningCandidateInfo(
std::vector<outliner::Candidate> &RepeatedSequenceLocs) const {
unsigned SequenceSize = std::accumulate(
RepeatedSequenceLocs[0].back()->isCall())
NumBytesToCreateFrame += 8;
- return outliner::TargetCostInfo(SequenceSize, NumBytesToCreateFrame, FrameID);
+ return outliner::OutlinedFunction(RepeatedSequenceLocs, SequenceSize,
+ NumBytesToCreateFrame, FrameID);
}
bool AArch64InstrInfo::isFunctionSafeToOutlineFrom(
void AArch64InstrInfo::buildOutlinedFrame(
MachineBasicBlock &MBB, MachineFunction &MF,
- const outliner::TargetCostInfo &TCI) const {
+ const outliner::OutlinedFunction &OF) const {
// For thunk outlining, rewrite the last instruction from a call to a
// tail-call.
- if (TCI.FrameConstructionID == MachineOutlinerThunk) {
+ if (OF.FrameConstructionID == MachineOutlinerThunk) {
MachineInstr *Call = &*--MBB.instr_end();
unsigned TailOpcode;
if (Call->getOpcode() == AArch64::BL) {
if (std::any_of(MBB.instr_begin(), MBB.instr_end(), IsNonTailCall)) {
// Fix up the instructions in the range, since we're going to modify the
// stack.
- assert(TCI.FrameConstructionID != MachineOutlinerDefault &&
+ assert(OF.FrameConstructionID != MachineOutlinerDefault &&
"Can only fix up stack references once");
fixupPostOutline(MBB);
MachineBasicBlock::iterator It = MBB.begin();
MachineBasicBlock::iterator Et = MBB.end();
- if (TCI.FrameConstructionID == MachineOutlinerTailCall ||
- TCI.FrameConstructionID == MachineOutlinerThunk)
+ if (OF.FrameConstructionID == MachineOutlinerTailCall ||
+ OF.FrameConstructionID == MachineOutlinerThunk)
Et = std::prev(MBB.end());
// Insert a save before the outlined region
}
// If this is a tail call outlined function, then there's already a return.
- if (TCI.FrameConstructionID == MachineOutlinerTailCall ||
- TCI.FrameConstructionID == MachineOutlinerThunk)
+ if (OF.FrameConstructionID == MachineOutlinerTailCall ||
+ OF.FrameConstructionID == MachineOutlinerThunk)
return;
// It's not a tail call, so we have to insert the return ourselves.
MBB.insert(MBB.end(), ret);
// Did we have to modify the stack by saving the link register?
- if (TCI.FrameConstructionID == MachineOutlinerNoLRSave)
+ if (OF.FrameConstructionID == MachineOutlinerNoLRSave)
return;
// We modified the stack.
bool isFunctionSafeToOutlineFrom(MachineFunction &MF,
bool OutlineFromLinkOnceODRs) const override;
- outliner::TargetCostInfo getOutliningCandidateInfo(
+ outliner::OutlinedFunction getOutliningCandidateInfo(
std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override;
outliner::InstrType
getOutliningType(MachineBasicBlock::iterator &MIT, unsigned Flags) const override;
unsigned getMachineOutlinerMBBFlags(MachineBasicBlock &MBB) const override;
void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF,
- const outliner::TargetCostInfo &TCI) const override;
+ const outliner::OutlinedFunction &OF) const override;
MachineBasicBlock::iterator
insertOutlinedCall(Module &M, MachineBasicBlock &MBB,
MachineBasicBlock::iterator &It, MachineFunction &MF,
MachineOutlinerTailCall
};
-outliner::TargetCostInfo X86InstrInfo::getOutliningCandidateInfo(
+outliner::OutlinedFunction X86InstrInfo::getOutliningCandidateInfo(
std::vector<outliner::Candidate> &RepeatedSequenceLocs) const {
unsigned SequenceSize =
std::accumulate(RepeatedSequenceLocs[0].front(),
for (outliner::Candidate &C : RepeatedSequenceLocs)
C.setCallInfo(MachineOutlinerTailCall, 1);
- return outliner::TargetCostInfo(SequenceSize,
- 0, // Number of bytes to emit frame.
- MachineOutlinerTailCall // Type of frame.
+ return outliner::OutlinedFunction(RepeatedSequenceLocs, SequenceSize,
+ 0, // Number of bytes to emit frame.
+ MachineOutlinerTailCall // Type of frame.
);
}
for (outliner::Candidate &C : RepeatedSequenceLocs)
C.setCallInfo(MachineOutlinerDefault, 1);
- return outliner::TargetCostInfo(SequenceSize, 1, MachineOutlinerDefault);
+ return outliner::OutlinedFunction(RepeatedSequenceLocs, SequenceSize, 1,
+ MachineOutlinerDefault);
}
bool X86InstrInfo::isFunctionSafeToOutlineFrom(MachineFunction &MF,
void X86InstrInfo::buildOutlinedFrame(MachineBasicBlock &MBB,
MachineFunction &MF,
- const outliner::TargetCostInfo &TCI)
+ const outliner::OutlinedFunction &OF)
const {
// If we're a tail call, we already have a return, so don't do anything.
- if (TCI.FrameConstructionID == MachineOutlinerTailCall)
+ if (OF.FrameConstructionID == MachineOutlinerTailCall)
return;
// We're a normal call, so our sequence doesn't have a return instruction.
ArrayRef<std::pair<unsigned, const char *>>
getSerializableDirectMachineOperandTargetFlags() const override;
- virtual outliner::TargetCostInfo getOutliningCandidateInfo(
+ virtual outliner::OutlinedFunction getOutliningCandidateInfo(
std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override;
bool isFunctionSafeToOutlineFrom(MachineFunction &MF,
getOutliningType(MachineBasicBlock::iterator &MIT, unsigned Flags) const override;
void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF,
- const outliner::TargetCostInfo &TCI) const override;
+ const outliner::OutlinedFunction &OF) const override;
MachineBasicBlock::iterator
insertOutlinedCall(Module &M, MachineBasicBlock &MBB,