unsigned FunctionIdx, unsigned Flags)
: StartIdx(StartIdx), Len(Len), FirstInst(FirstInst), LastInst(LastInst),
MBB(MBB), FunctionIdx(FunctionIdx), Flags(Flags) {}
- Candidate() = default;
+ Candidate() = delete;
/// Used to ensure that \p Candidates are outlined in an order that
/// preserves the start and end indices of other \p Candidates.
C.Benefit = B;
}
- OutlinedFunction() = default;
+ OutlinedFunction() = delete;
};
} // namespace outliner
} // namespace llvm
}
/// Returns a \p outliner::OutlinedFunction struct containing target-specific
- /// information for a set of outlining candidates.
- virtual outliner::OutlinedFunction getOutliningCandidateInfo(
+ /// information for a set of outlining candidates. Returns None if the
+ /// candidates are not suitable for outlining.
+ virtual std::optional<outliner::OutlinedFunction> getOutliningCandidateInfo(
std::vector<outliner::Candidate> &RepeatedSequenceLocs) const {
llvm_unreachable(
"Target didn't implement TargetInstrInfo::getOutliningCandidateInfo!");
const TargetInstrInfo *TII =
CandidatesForRepeatedSeq[0].getMF()->getSubtarget().getInstrInfo();
- OutlinedFunction OF =
+ std::optional<OutlinedFunction> OF =
TII->getOutliningCandidateInfo(CandidatesForRepeatedSeq);
// If we deleted too many candidates, then there's nothing worth outlining.
// FIXME: This should take target-specified instruction sizes into account.
- if (OF.Candidates.size() < 2)
+ if (!OF || OF->Candidates.size() < 2)
continue;
// Is it better to outline this candidate than not?
- if (OF.getBenefit() < 1) {
- emitNotOutliningCheaperRemark(StringLen, CandidatesForRepeatedSeq, OF);
+ if (OF->getBenefit() < 1) {
+ emitNotOutliningCheaperRemark(StringLen, CandidatesForRepeatedSeq, *OF);
continue;
}
- FunctionList.push_back(OF);
+ FunctionList.push_back(*OF);
}
}
return SubtargetA.hasV8_3aOps() == SubtargetB.hasV8_3aOps();
}
-outliner::OutlinedFunction AArch64InstrInfo::getOutliningCandidateInfo(
+std::optional<outliner::OutlinedFunction>
+AArch64InstrInfo::getOutliningCandidateInfo(
std::vector<outliner::Candidate> &RepeatedSequenceLocs) const {
outliner::Candidate &FirstCand = RepeatedSequenceLocs[0];
unsigned SequenceSize =
}
return true;
}) != RepeatedSequenceLocs.end()) {
- return outliner::OutlinedFunction();
+ return std::nullopt;
}
// Since at this point all candidates agree on their return address signing
// If the sequence doesn't have enough candidates left, then we're done.
if (RepeatedSequenceLocs.size() < 2)
- return outliner::OutlinedFunction();
+ return std::nullopt;
}
// Properties about candidate MBBs that hold for all of them.
C.getMF()->getFrameInstructions();
if (CFICount > 0 && CFICount != CFIInstructions.size())
- return outliner::OutlinedFunction();
+ return std::nullopt;
}
// Returns true if an instructions is safe to fix up, false otherwise.
// If we dropped all of the candidates, bail out here.
if (RepeatedSequenceLocs.size() < 2) {
RepeatedSequenceLocs.clear();
- return outliner::OutlinedFunction();
+ return std::nullopt;
}
}
// We can't fix up the stack. Bail out.
if (!AllStackInstrsSafe) {
RepeatedSequenceLocs.clear();
- return outliner::OutlinedFunction();
+ return std::nullopt;
}
// Save + restore LR.
// If we have CFI instructions, we can only outline if the outlined section
// can be a tail call
if (FrameID != MachineOutlinerTailCall && CFICount > 0)
- return outliner::OutlinedFunction();
+ return std::nullopt;
return outliner::OutlinedFunction(RepeatedSequenceLocs, SequenceSize,
NumBytesToCreateFrame, FrameID);
#include "AArch64RegisterInfo.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/Support/TypeSize.h"
+#include <optional>
#define GET_INSTRINFO_HEADER
#include "AArch64GenInstrInfo.inc"
bool isFunctionSafeToOutlineFrom(MachineFunction &MF,
bool OutlineFromLinkOnceODRs) const override;
- outliner::OutlinedFunction getOutliningCandidateInfo(
+ std::optional<outliner::OutlinedFunction> getOutliningCandidateInfo(
std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override;
outliner::InstrType
getOutliningTypeImpl(MachineBasicBlock::iterator &MIT, unsigned Flags) const override;
return !Live;
}
-outliner::OutlinedFunction ARMBaseInstrInfo::getOutliningCandidateInfo(
+std::optional<outliner::OutlinedFunction>
+ARMBaseInstrInfo::getOutliningCandidateInfo(
std::vector<outliner::Candidate> &RepeatedSequenceLocs) const {
outliner::Candidate &FirstCand = RepeatedSequenceLocs[0];
unsigned SequenceSize =
// If the sequence doesn't have enough candidates left, then we're done.
if (RepeatedSequenceLocs.size() < 2)
- return outliner::OutlinedFunction();
+ return std::nullopt;
}
// We expect the majority of the outlining candidates to be in consensus with
RepeatedSequenceLocs.erase(RepeatedSequenceLocs.begin(), NoBTI);
if (RepeatedSequenceLocs.size() < 2)
- return outliner::OutlinedFunction();
+ return std::nullopt;
// Likewise, partition the candidates according to PAC-RET enablement.
auto NoPAC =
RepeatedSequenceLocs.erase(RepeatedSequenceLocs.begin(), NoPAC);
if (RepeatedSequenceLocs.size() < 2)
- return outliner::OutlinedFunction();
+ return std::nullopt;
// At this point, we have only "safe" candidates to outline. Figure out
// frame + call instruction information.
/// ARM supports the MachineOutliner.
bool isFunctionSafeToOutlineFrom(MachineFunction &MF,
bool OutlineFromLinkOnceODRs) const override;
- outliner::OutlinedFunction getOutliningCandidateInfo(
+ std::optional<outliner::OutlinedFunction> getOutliningCandidateInfo(
std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override;
void mergeOutliningCandidateAttributes(
Function &F, std::vector<outliner::Candidate> &Candidates) const override;
return MF.getFunction().hasMinSize();
}
-outliner::OutlinedFunction RISCVInstrInfo::getOutliningCandidateInfo(
+std::optional<outliner::OutlinedFunction>
+RISCVInstrInfo::getOutliningCandidateInfo(
std::vector<outliner::Candidate> &RepeatedSequenceLocs) const {
// First we need to filter out candidates where the X5 register (IE t0) can't
// If the sequence doesn't have enough candidates left, then we're done.
if (RepeatedSequenceLocs.size() < 2)
- return outliner::OutlinedFunction();
+ return std::nullopt;
unsigned SequenceSize = 0;
bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override;
// Calculate target-specific information for a set of outlining candidates.
- outliner::OutlinedFunction getOutliningCandidateInfo(
+ std::optional<outliner::OutlinedFunction> getOutliningCandidateInfo(
std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override;
// Return if/how a given MachineInstr should be outlined.
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetOptions.h"
+#include <optional>
using namespace llvm;
MachineOutlinerTailCall
};
-outliner::OutlinedFunction X86InstrInfo::getOutliningCandidateInfo(
+std::optional<outliner::OutlinedFunction>
+X86InstrInfo::getOutliningCandidateInfo(
std::vector<outliner::Candidate> &RepeatedSequenceLocs) const {
unsigned SequenceSize =
std::accumulate(RepeatedSequenceLocs[0].front(),
C.getMF()->getFrameInstructions();
if (CFICount > 0 && CFICount != CFIInstructions.size())
- return outliner::OutlinedFunction();
+ return std::nullopt;
}
// FIXME: Use real size in bytes for call and ret instructions.
}
if (CFICount > 0)
- return outliner::OutlinedFunction();
+ return std::nullopt;
for (outliner::Candidate &C : RepeatedSequenceLocs)
C.setCallInfo(MachineOutlinerDefault, 1);
ArrayRef<std::pair<unsigned, const char *>>
getSerializableDirectMachineOperandTargetFlags() const override;
- outliner::OutlinedFunction getOutliningCandidateInfo(
+ std::optional<outliner::OutlinedFunction> getOutliningCandidateInfo(
std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override;
bool isFunctionSafeToOutlineFrom(MachineFunction &MF,