#include "HexagonRegisterInfo.h"
#include "HexagonSubtarget.h"
#include "HexagonTargetMachine.h"
+#include "MCTargetDesc/HexagonBaseInfo.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/LivePhysRegs.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachinePostDominators.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
+#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Function.h"
-#include "llvm/IR/Type.h"
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CodeGen.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetOptions.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <iterator>
+#include <limits>
+#include <map>
+#include <new>
+#include <utility>
+#include <vector>
// Hexagon stack frame layout as defined by the ABI:
//
// alignment)
// A - required alignment
-
using namespace llvm;
static cl::opt<bool> DisableDeallocRet("disable-hexagon-dealloc-ret",
cl::init(true), cl::Hidden, cl::ZeroOrMore,
cl::desc("Enable stack frame shrink wrapping"));
-static cl::opt<unsigned> ShrinkLimit("shrink-frame-limit", cl::init(UINT_MAX),
- cl::Hidden, cl::ZeroOrMore, cl::desc("Max count of stack frame "
- "shrink-wraps"));
+static cl::opt<unsigned> ShrinkLimit("shrink-frame-limit",
+ cl::init(std::numeric_limits<unsigned>::max()), cl::Hidden, cl::ZeroOrMore,
+ cl::desc("Max count of stack frame shrink-wraps"));
static cl::opt<bool> EnableSaveRestoreLong("enable-save-restore-long",
cl::Hidden, cl::desc("Enable long calls for save-restore stubs."),
#ifndef NDEBUG
static cl::opt<unsigned> SpillOptMax("spill-opt-max", cl::Hidden,
- cl::init(UINT_MAX));
+ cl::init(std::numeric_limits<unsigned>::max()));
static unsigned SpillOptCount = 0;
#endif
-
namespace llvm {
+
void initializeHexagonCallFrameInformationPass(PassRegistry&);
FunctionPass *createHexagonCallFrameInformation();
-}
+
+} // end namespace llvm
namespace {
+
class HexagonCallFrameInformation : public MachineFunctionPass {
public:
static char ID;
+
HexagonCallFrameInformation() : MachineFunctionPass(ID) {
PassRegistry &PR = *PassRegistry::getPassRegistry();
initializeHexagonCallFrameInformationPass(PR);
}
+
bool runOnMachineFunction(MachineFunction &MF) override;
+
MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties().set(
MachineFunctionProperties::Property::NoVRegs);
};
char HexagonCallFrameInformation::ID = 0;
-}
+
+} // end anonymous namespace
bool HexagonCallFrameInformation::runOnMachineFunction(MachineFunction &MF) {
auto &HFI = *MF.getSubtarget<HexagonSubtarget>().getFrameLowering();
return new HexagonCallFrameInformation();
}
-
-namespace {
- /// Map a register pair Reg to the subregister that has the greater "number",
- /// i.e. D3 (aka R7:6) will be mapped to R7, etc.
- unsigned getMax32BitSubRegister(unsigned Reg, const TargetRegisterInfo &TRI,
- bool hireg = true) {
+/// Map a register pair Reg to the subregister that has the greater "number",
+/// i.e. D3 (aka R7:6) will be mapped to R7, etc.
+static unsigned getMax32BitSubRegister(unsigned Reg,
+ const TargetRegisterInfo &TRI,
+ bool hireg = true) {
if (Reg < Hexagon::D0 || Reg > Hexagon::D15)
return Reg;
}
}
return RegNo;
- }
+}
- /// Returns the callee saved register with the largest id in the vector.
- unsigned getMaxCalleeSavedReg(const std::vector<CalleeSavedInfo> &CSI,
- const TargetRegisterInfo &TRI) {
+/// Returns the callee saved register with the largest id in the vector.
+static unsigned getMaxCalleeSavedReg(const std::vector<CalleeSavedInfo> &CSI,
+ const TargetRegisterInfo &TRI) {
static_assert(Hexagon::R1 > 0,
"Assume physical registers are encoded as positive integers");
if (CSI.empty())
Max = Reg;
}
return Max;
- }
+}
- /// Checks if the basic block contains any instruction that needs a stack
- /// frame to be already in place.
- bool needsStackFrame(const MachineBasicBlock &MBB, const BitVector &CSR,
- const HexagonRegisterInfo &HRI) {
+/// Checks if the basic block contains any instruction that needs a stack
+/// frame to be already in place.
+static bool needsStackFrame(const MachineBasicBlock &MBB, const BitVector &CSR,
+ const HexagonRegisterInfo &HRI) {
for (auto &I : MBB) {
const MachineInstr *MI = &I;
if (MI->isCall())
}
}
return false;
- }
+}
/// Returns true if MBB has a machine instructions that indicates a tail call
/// in the block.
- bool hasTailCall(const MachineBasicBlock &MBB) {
+static bool hasTailCall(const MachineBasicBlock &MBB) {
MachineBasicBlock::const_iterator I = MBB.getLastNonDebugInstr();
unsigned RetOpc = I->getOpcode();
return RetOpc == Hexagon::PS_tailcall_i || RetOpc == Hexagon::PS_tailcall_r;
- }
+}
- /// Returns true if MBB contains an instruction that returns.
- bool hasReturn(const MachineBasicBlock &MBB) {
+/// Returns true if MBB contains an instruction that returns.
+static bool hasReturn(const MachineBasicBlock &MBB) {
for (auto I = MBB.getFirstTerminator(), E = MBB.end(); I != E; ++I)
if (I->isReturn())
return true;
return false;
- }
+}
- /// Returns the "return" instruction from this block, or nullptr if there
- /// isn't any.
- MachineInstr *getReturn(MachineBasicBlock &MBB) {
+/// Returns the "return" instruction from this block, or nullptr if there
+/// isn't any.
+static MachineInstr *getReturn(MachineBasicBlock &MBB) {
for (auto &I : MBB)
if (I.isReturn())
return &I;
return nullptr;
- }
+}
- bool isRestoreCall(unsigned Opc) {
+static bool isRestoreCall(unsigned Opc) {
switch (Opc) {
case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
return true;
}
return false;
- }
+}
- inline bool isOptNone(const MachineFunction &MF) {
+static inline bool isOptNone(const MachineFunction &MF) {
return MF.getFunction()->hasFnAttribute(Attribute::OptimizeNone) ||
MF.getTarget().getOptLevel() == CodeGenOpt::None;
- }
+}
- inline bool isOptSize(const MachineFunction &MF) {
+static inline bool isOptSize(const MachineFunction &MF) {
const Function &F = *MF.getFunction();
return F.optForSize() && !F.optForMinSize();
- }
+}
- inline bool isMinSize(const MachineFunction &MF) {
+static inline bool isMinSize(const MachineFunction &MF) {
return MF.getFunction()->optForMinSize();
- }
}
-
/// Implements shrink-wrapping of the stack frame. By default, stack frame
/// is created in the function entry block, and is cleaned up in every block
/// that returns. This function finds alternate blocks: one for the frame
EpilogB = PDomB;
}
-
/// Perform most of the PEI work here:
/// - saving/restoring of the callee-saved registers,
/// - stack frame creation and destruction.
}
}
-
void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &MBB,
bool PrologueStubs) const {
MachineFunction &MF = *MBB.getParent();
return ReachedExit;
}
-
-namespace {
- Optional<MachineBasicBlock::iterator> findCFILocation(MachineBasicBlock &B) {
+static Optional<MachineBasicBlock::iterator>
+findCFILocation(MachineBasicBlock &B) {
// The CFI instructions need to be inserted right after allocframe.
// An exception to this is a situation where allocframe is bundled
// with a call: then the CFI instructions need to be inserted before
return HasCall ? It : std::next(It);
}
return None;
- }
}
-
void HexagonFrameLowering::insertCFIInstructions(MachineFunction &MF) const {
for (auto &B : MF) {
auto At = findCFILocation(B);
}
}
-
void HexagonFrameLowering::insertCFIInstructionsAt(MachineBasicBlock &MBB,
MachineBasicBlock::iterator At) const {
MachineFunction &MF = *MBB.getParent();
}
}
-
bool HexagonFrameLowering::hasFP(const MachineFunction &MF) const {
auto &MFI = MF.getFrameInfo();
auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
return false;
}
-
enum SpillKind {
SK_ToMem,
SK_FromMem,
default:
llvm_unreachable("Unhandled maximum callee save register");
}
- return 0;
+ return nullptr;
}
-
int HexagonFrameLowering::getFrameIndexReference(const MachineFunction &MF,
int FI, unsigned &FrameReg) const {
auto &MFI = MF.getFrameInfo();
return RealOffset;
}
-
bool HexagonFrameLowering::insertCSRSpillsInBlock(MachineBasicBlock &MBB,
const CSIVect &CSI, const HexagonRegisterInfo &HRI,
bool &PrologueStubs) const {
return true;
}
-
bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &MBB,
const CSIVect &CSI, const HexagonRegisterInfo &HRI) const {
if (CSI.empty())
return MBB.erase(I);
}
-
void HexagonFrameLowering::processFunctionBeforeFrameFinalized(
MachineFunction &MF, RegScavenger *RS) const {
// If this function has uses aligned stack and also has variable sized stack
return true;
}
-
#ifndef NDEBUG
static void dump_registers(BitVector &Regs, const TargetRegisterInfo &TRI) {
dbgs() << '{';
}
#endif
-
bool HexagonFrameLowering::assignCalleeSavedSpillSlots(MachineFunction &MF,
const TargetRegisterInfo *TRI, std::vector<CalleeSavedInfo> &CSI) const {
DEBUG(dbgs() << __func__ << " on "
return true;
}
-
bool HexagonFrameLowering::expandStoreVecPred(MachineBasicBlock &B,
MachineBasicBlock::iterator It, MachineRegisterInfo &MRI,
const HexagonInstrInfo &HII, SmallVectorImpl<unsigned> &NewRegs) const {
return true;
}
-
bool HexagonFrameLowering::expandSpillMacros(MachineFunction &MF,
SmallVectorImpl<unsigned> &NewRegs) const {
auto &HST = MF.getSubtarget<HexagonSubtarget>();
return Changed;
}
-
void HexagonFrameLowering::determineCalleeSaves(MachineFunction &MF,
BitVector &SavedRegs,
RegScavenger *RS) const {
TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
}
-
unsigned HexagonFrameLowering::findPhysReg(MachineFunction &MF,
HexagonBlockRanges::IndexRange &FIR,
HexagonBlockRanges::InstrIndexMap &IndexMap,
struct SlotInfo {
BlockRangeMap Map;
- unsigned Size;
- const TargetRegisterClass *RC;
+ unsigned Size = 0;
+ const TargetRegisterClass *RC = nullptr;
- SlotInfo() : Map(), Size(0), RC(nullptr) {}
+ SlotInfo() = default;
};
BlockIndexMap BlockIndexes;
}
}
-
bool HexagonFrameLowering::needsAligna(const MachineFunction &MF) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
if (!MFI.hasVarSizedObjects())
return true;
}
-
const MachineInstr *HexagonFrameLowering::getAlignaInstr(
const MachineFunction &MF) const {
for (auto &B : MF)
return nullptr;
}
-
/// Adds all callee-saved registers as implicit uses or defs to the
/// instruction.
void HexagonFrameLowering::addCalleeSaveRegistersAsImpOperand(MachineInstr *MI,
MI->addOperand(MachineOperand::CreateReg(R.getReg(), IsDef, true, IsKill));
}
-
/// Determine whether the callee-saved register saves and restores should
/// be generated via inline code. If this function returns "true", inline
/// code will be generated. If this function returns "false", additional
return false;
}
-
bool HexagonFrameLowering::useSpillFunction(MachineFunction &MF,
const CSIVect &CSI) const {
if (shouldInlineCSR(MF, CSI))
return Threshold < NumCSI;
}
-
bool HexagonFrameLowering::useRestoreFunction(MachineFunction &MF,
const CSIVect &CSI) const {
if (shouldInlineCSR(MF, CSI))
return Threshold < NumCSI;
}
-
bool HexagonFrameLowering::mayOverflowFrameOffset(MachineFunction &MF) const {
unsigned StackSize = MF.getFrameInfo().estimateStackSize(MF);
auto &HST = MF.getSubtarget<HexagonSubtarget>();
return StackSize > 256;
return false;
}
-
#include "Hexagon.h"
#include "HexagonBlockRanges.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/Target/TargetFrameLowering.h"
+#include <vector>
namespace llvm {
override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const
override {}
+
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const override {
return true;
}
+
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const override {
bool targetHandlesStackFrameRounding() const override {
return true;
}
+
int getFrameIndexReference(const MachineFunction &MF, int FI,
unsigned &FrameReg) const override;
bool hasFP(const MachineFunction &MF) const override;
bool mayOverflowFrameOffset(MachineFunction &MF) const;
};
-} // End llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONFRAMELOWERING_H
#define DEBUG_TYPE "hexmux"
-#include "llvm/CodeGen/Passes.h"
+#include "HexagonInstrInfo.h"
+#include "HexagonRegisterInfo.h"
+#include "HexagonSubtarget.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "HexagonTargetMachine.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
+#include <limits>
+#include <iterator>
+#include <utility>
using namespace llvm;
namespace llvm {
+
FunctionPass *createHexagonGenMux();
void initializeHexagonGenMuxPass(PassRegistry& Registry);
-}
+
+} // end namespace llvm
namespace {
+
class HexagonGenMux : public MachineFunctionPass {
public:
static char ID;
- HexagonGenMux() : MachineFunctionPass(ID), HII(0), HRI(0) {
+
+ HexagonGenMux() : MachineFunctionPass(ID), HII(nullptr), HRI(nullptr) {
initializeHexagonGenMuxPass(*PassRegistry::getPassRegistry());
}
+
StringRef getPassName() const override {
return "Hexagon generate mux instructions";
}
+
void getAnalysisUsage(AnalysisUsage &AU) const override {
MachineFunctionPass::getAnalysisUsage(AU);
}
+
bool runOnMachineFunction(MachineFunction &MF) override;
+
MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties().set(
MachineFunctionProperties::Property::NoVRegs);
const HexagonRegisterInfo *HRI;
struct CondsetInfo {
- unsigned PredR;
- unsigned TrueX, FalseX;
- CondsetInfo() : PredR(0), TrueX(UINT_MAX), FalseX(UINT_MAX) {}
+ unsigned PredR = 0;
+ unsigned TrueX = std::numeric_limits<unsigned>::max();
+ unsigned FalseX = std::numeric_limits<unsigned>::max();
+
+ CondsetInfo() = default;
};
+
struct DefUseInfo {
BitVector Defs, Uses;
- DefUseInfo() : Defs(), Uses() {}
+
+ DefUseInfo() = default;
DefUseInfo(const BitVector &D, const BitVector &U) : Defs(D), Uses(U) {}
};
+
struct MuxInfo {
MachineBasicBlock::iterator At;
unsigned DefR, PredR;
MachineOperand *SrcT, *SrcF;
MachineInstr *Def1, *Def2;
+
MuxInfo(MachineBasicBlock::iterator It, unsigned DR, unsigned PR,
MachineOperand *TOp, MachineOperand *FOp, MachineInstr &D1,
MachineInstr &D2)
: At(It), DefR(DR), PredR(PR), SrcT(TOp), SrcF(FOp), Def1(&D1),
Def2(&D2) {}
};
+
typedef DenseMap<MachineInstr*,unsigned> InstrIndexMap;
typedef DenseMap<unsigned,DefUseInfo> DefUseInfoMap;
typedef SmallVector<MuxInfo,4> MuxInfoList;
bool isRegPair(unsigned Reg) const {
return Hexagon::DoubleRegsRegClass.contains(Reg);
}
+
void getSubRegs(unsigned Reg, BitVector &SRs) const;
void expandReg(unsigned Reg, BitVector &Set) const;
void getDefsUses(const MachineInstr *MI, BitVector &Defs,
};
char HexagonGenMux::ID = 0;
-}
+
+} // end anonymous namespace
INITIALIZE_PASS(HexagonGenMux, "hexagon-mux",
"Hexagon generate mux instructions", false, false)
-
void HexagonGenMux::getSubRegs(unsigned Reg, BitVector &SRs) const {
for (MCSubRegIterator I(Reg, HRI); I.isValid(); ++I)
SRs[*I] = true;
}
-
void HexagonGenMux::expandReg(unsigned Reg, BitVector &Set) const {
if (isRegPair(Reg))
getSubRegs(Reg, Set);
Set[Reg] = true;
}
-
void HexagonGenMux::getDefsUses(const MachineInstr *MI, BitVector &Defs,
BitVector &Uses) const {
// First, get the implicit defs and uses for this instruction.
}
}
-
void HexagonGenMux::buildMaps(MachineBasicBlock &B, InstrIndexMap &I2X,
DefUseInfoMap &DUM) {
unsigned Index = 0;
}
}
-
bool HexagonGenMux::isCondTransfer(unsigned Opc) const {
switch (Opc) {
case Hexagon::A2_tfrt:
return false;
}
-
unsigned HexagonGenMux::getMuxOpcode(const MachineOperand &Src1,
const MachineOperand &Src2) const {
bool IsReg1 = Src1.isReg(), IsReg2 = Src2.isReg();
return 0;
}
-
bool HexagonGenMux::genMuxInBlock(MachineBasicBlock &B) {
bool Changed = false;
InstrIndexMap I2X;
CI.TrueX = Idx;
else
CI.FalseX = Idx;
- if (CI.TrueX == UINT_MAX || CI.FalseX == UINT_MAX)
+ if (CI.TrueX == std::numeric_limits<unsigned>::max() ||
+ CI.FalseX == std::numeric_limits<unsigned>::max())
continue;
// There is now a complete definition of DR, i.e. we have the predicate
#define DEBUG_TYPE "gen-pred"
-#include "HexagonTargetMachine.h"
+#include "HexagonInstrInfo.h"
+#include "HexagonSubtarget.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetMachine.h"
-
-#include <functional>
+#include "llvm/Target/TargetRegisterInfo.h"
+#include <cassert>
+#include <iterator>
+#include <map>
#include <queue>
#include <set>
+#include <utility>
using namespace llvm;
namespace llvm {
+
void initializeHexagonGenPredicatePass(PassRegistry& Registry);
FunctionPass *createHexagonGenPredicate();
-}
+
+} // end namespace llvm
namespace {
+
struct Register {
unsigned R, S;
+
Register(unsigned r = 0, unsigned s = 0) : R(r), S(s) {}
Register(const MachineOperand &MO) : R(MO.getReg()), S(MO.getSubReg()) {}
+
bool operator== (const Register &Reg) const {
return R == Reg.R && S == Reg.S;
}
+
bool operator< (const Register &Reg) const {
return R < Reg.R || (R == Reg.R && S < Reg.S);
}
};
+
struct PrintRegister {
- PrintRegister(Register R, const TargetRegisterInfo &I) : Reg(R), TRI(I) {}
friend raw_ostream &operator<< (raw_ostream &OS, const PrintRegister &PR);
+
+ PrintRegister(Register R, const TargetRegisterInfo &I) : Reg(R), TRI(I) {}
+
private:
Register Reg;
const TargetRegisterInfo &TRI;
};
+
raw_ostream &operator<< (raw_ostream &OS, const PrintRegister &PR)
LLVM_ATTRIBUTE_UNUSED;
raw_ostream &operator<< (raw_ostream &OS, const PrintRegister &PR) {
class HexagonGenPredicate : public MachineFunctionPass {
public:
static char ID;
- HexagonGenPredicate() : MachineFunctionPass(ID), TII(0), TRI(0), MRI(0) {
+
+ HexagonGenPredicate() : MachineFunctionPass(ID), TII(nullptr), TRI(nullptr),
+ MRI(nullptr) {
initializeHexagonGenPredicatePass(*PassRegistry::getPassRegistry());
}
- virtual StringRef getPassName() const {
+
+ StringRef getPassName() const override {
return "Hexagon generate predicate operations";
}
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<MachineDominatorTree>();
AU.addPreserved<MachineDominatorTree>();
MachineFunctionPass::getAnalysisUsage(AU);
}
- virtual bool runOnMachineFunction(MachineFunction &MF);
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
private:
typedef SetVector<MachineInstr*> VectOfInst;
};
char HexagonGenPredicate::ID = 0;
-}
+
+} // end anonymous namespace
INITIALIZE_PASS_BEGIN(HexagonGenPredicate, "hexagon-gen-pred",
"Hexagon generate predicate operations", false, false)
return RC == &Hexagon::PredRegsRegClass;
}
-
unsigned HexagonGenPredicate::getPredForm(unsigned Opc) {
using namespace Hexagon;
return 0;
}
-
bool HexagonGenPredicate::isConvertibleToPredForm(const MachineInstr *MI) {
unsigned Opc = MI->getOpcode();
if (getPredForm(Opc) != 0)
return false;
}
-
void HexagonGenPredicate::collectPredicateGPR(MachineFunction &MF) {
for (MachineFunction::iterator A = MF.begin(), Z = MF.end(); A != Z; ++A) {
MachineBasicBlock &B = *A;
}
}
-
void HexagonGenPredicate::processPredicateGPR(const Register &Reg) {
DEBUG(dbgs() << __func__ << ": "
<< PrintReg(Reg.R, TRI, Reg.S) << "\n");
}
}
-
Register HexagonGenPredicate::getPredRegFor(const Register &Reg) {
// Create a predicate register for a given Reg. The newly created register
// will have its value copied from Reg, so that it can be later used as
llvm_unreachable("Invalid argument");
}
-
bool HexagonGenPredicate::isScalarCmp(unsigned Opc) {
switch (Opc) {
case Hexagon::C2_cmpeq:
return false;
}
-
bool HexagonGenPredicate::isScalarPred(Register PredReg) {
std::queue<Register> WorkQ;
WorkQ.push(PredReg);
return true;
}
-
bool HexagonGenPredicate::convertToPredForm(MachineInstr *MI) {
DEBUG(dbgs() << __func__ << ": " << MI << " " << *MI);
return true;
}
-
bool HexagonGenPredicate::eliminatePredCopies(MachineFunction &MF) {
DEBUG(dbgs() << __func__ << "\n");
const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
return Changed;
}
-
bool HexagonGenPredicate::runOnMachineFunction(MachineFunction &MF) {
if (skipFunction(*MF.getFunction()))
return false;
return Changed;
}
-
FunctionPass *llvm::createHexagonGenPredicate() {
return new HexagonGenPredicate();
}
-
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/SmallSet.h"
-#include "Hexagon.h"
+#include "HexagonInstrInfo.h"
#include "HexagonSubtarget.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/PassSupport.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include <algorithm>
+#include "llvm/Target/TargetRegisterInfo.h"
+#include <cassert>
+#include <cstdint>
+#include <cstdlib>
+#include <iterator>
+#include <map>
+#include <set>
+#include <utility>
#include <vector>
using namespace llvm;
STATISTIC(NumHWLoops, "Number of loops converted to hardware loops");
namespace llvm {
+
FunctionPass *createHexagonHardwareLoops();
void initializeHexagonHardwareLoopsPass(PassRegistry&);
-}
+
+} // end namespace llvm
namespace {
+
class CountValue;
+
struct HexagonHardwareLoops : public MachineFunctionPass {
MachineLoopInfo *MLI;
MachineRegisterInfo *MRI;
static bool isUnsigned(Kind Cmp) {
return (Cmp & U);
}
-
};
/// \brief Find the register that contains the loop controlling
CV_Register,
CV_Immediate
};
+
private:
CountValueType Kind;
union Values {
Contents.ImmVal = v;
}
}
+
bool isReg() const { return Kind == CV_Register; }
bool isImm() const { return Kind == CV_Immediate; }
if (isImm()) { OS << Contents.ImmVal; }
}
};
-} // end anonymous namespace
+} // end anonymous namespace
INITIALIZE_PASS_BEGIN(HexagonHardwareLoops, "hwloops",
"Hexagon Hardware Loops", false, false)
// the fall through can go to the header.
assert (TB && "Exit block without a branch?");
if (ExitingBlock != Latch && (TB == Latch || FB == Latch)) {
- MachineBasicBlock *LTB = 0, *LFB = 0;
+ MachineBasicBlock *LTB = nullptr, *LFB = nullptr;
SmallVector<MachineOperand,2> LCond;
bool NotAnalyzed = TII->analyzeBranch(*Latch, LTB, LFB, LCond, false);
if (NotAnalyzed)
// Determine the loop start.
MachineBasicBlock *TopBlock = L->getTopBlock();
MachineBasicBlock *ExitingBlock = L->findLoopControlBlock();
- MachineBasicBlock *LoopStart = 0;
+ MachineBasicBlock *LoopStart = nullptr;
if (ExitingBlock != L->getLoopLatch()) {
- MachineBasicBlock *TB = 0, *FB = 0;
+ MachineBasicBlock *TB = nullptr, *FB = nullptr;
SmallVector<MachineOperand, 2> Cond;
if (TII->analyzeBranch(*ExitingBlock, TB, FB, Cond, false))
if (!TII->analyzeCompare(*MI, CmpReg1, CmpReg2, CmpMask, CmpValue))
continue;
- MachineBasicBlock *TBB = 0, *FBB = 0;
+ MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
SmallVector<MachineOperand, 2> Cond;
if (TII->analyzeBranch(*MI->getParent(), TBB, FBB, Cond, false))
continue;
- Comparison::Kind Cmp = getComparisonKind(MI->getOpcode(), 0, 0, 0);
+ Comparison::Kind Cmp =
+ getComparisonKind(MI->getOpcode(), nullptr, nullptr, 0);
if (Cmp == 0)
continue;
if (TII->predOpcodeHasNot(Cond) ^ (TBB != MBB))
return false;
if (ExitingBlock != Latch && (TB == Latch || FB == Latch)) {
- MachineBasicBlock *LTB = 0, *LFB = 0;
+ MachineBasicBlock *LTB = nullptr, *LFB = nullptr;
SmallVector<MachineOperand,2> LCond;
bool NotAnalyzed = TII->analyzeBranch(*Latch, LTB, LFB, LCond, false);
if (NotAnalyzed)
// It is not valid to do this transformation on an unsigned comparison
// because it may underflow.
- Comparison::Kind Cmp = getComparisonKind(PredDef->getOpcode(), 0, 0, 0);
+ Comparison::Kind Cmp =
+ getComparisonKind(PredDef->getOpcode(), nullptr, nullptr, 0);
if (!Cmp || Comparison::isUnsigned(Cmp))
return false;
PN->addOperand(MachineOperand::CreateReg(NewPR, false));
PN->addOperand(MachineOperand::CreateMBB(NewPH));
}
-
} else {
assert(Header->pred_size() == 2);
#define DEBUG_TYPE "opt-addr-mode"
-#include "HexagonTargetMachine.h"
+#include "HexagonInstrInfo.h"
+#include "HexagonSubtarget.h"
+#include "MCTargetDesc/HexagonBaseInfo.h"
#include "RDFGraph.h"
#include "RDFLiveness.h"
-
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineDominanceFrontier.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegisterInfo.h"
+#include <cassert>
+#include <cstdint>
+#include <map>
static cl::opt<int> CodeGrowthLimit("hexagon-amode-growth-limit",
cl::Hidden, cl::init(0), cl::desc("Code growth limit for address mode "
using namespace rdf;
namespace llvm {
+
FunctionPass *createHexagonOptAddrMode();
void initializeHexagonOptAddrModePass(PassRegistry &);
-}
+
+} // end namespace llvm
namespace {
+
class HexagonOptAddrMode : public MachineFunctionPass {
public:
static char ID;
+
HexagonOptAddrMode()
- : MachineFunctionPass(ID), HII(0), MDT(0), DFG(0), LV(0) {
+ : MachineFunctionPass(ID), HII(nullptr), MDT(nullptr), DFG(nullptr),
+ LV(nullptr) {
PassRegistry &R = *PassRegistry::getPassRegistry();
initializeHexagonOptAddrModePass(R);
}
+
StringRef getPassName() const override {
return "Optimize addressing mode of load/store";
}
+
void getAnalysisUsage(AnalysisUsage &AU) const override {
MachineFunctionPass::getAnalysisUsage(AU);
AU.addRequired<MachineDominatorTree>();
AU.addRequired<MachineDominanceFrontier>();
AU.setPreservesAll();
}
+
bool runOnMachineFunction(MachineFunction &MF) override;
private:
bool changeAddAsl(NodeAddr<UseNode *> AddAslUN, MachineInstr *AddAslMI,
const MachineOperand &ImmOp, unsigned ImmOpNum);
};
-}
+
+} // end anonymous namespace
char HexagonOptAddrMode::ID = 0;
const Liveness::RefMap &phiUse = LV->getRealUses(id);
DEBUG(dbgs() << "\t\t\t\tphi real Uses"
<< Print<Liveness::RefMap>(phiUse, *DFG) << "\n");
- if (phiUse.size() > 0) {
+ if (!phiUse.empty()) {
for (auto I : phiUse) {
if (DR.Reg != I.first)
continue;