#include "HexagonISelDAGToDAG.h"
#include "Hexagon.h"
#include "HexagonISelLowering.h"
#include "HexagonMachineFunctionInfo.h"
#include "HexagonTargetMachine.h"
#include "llvm/CodeGen/FunctionLoweringInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsHexagon.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
usingnamespacellvm;
#define DEBUG_TYPE …
#define PASS_NAME …
static
cl::opt<bool>
EnableAddressRebalancing("isel-rebalance-addr", cl::Hidden, cl::init(true),
cl::desc("Rebalance address calculation trees to improve "
"instruction selection"));
static
cl::opt<bool>
RebalanceOnlyForOptimizations("rebalance-only-opt", cl::Hidden, cl::init(false),
cl::desc("Rebalance address tree only if this allows optimizations"));
static
cl::opt<bool>
RebalanceOnlyImbalancedTrees("rebalance-only-imbal", cl::Hidden,
cl::init(false), cl::desc("Rebalance address tree only if it is imbalanced"));
static cl::opt<bool> CheckSingleUse("hexagon-isel-su", cl::Hidden,
cl::init(true), cl::desc("Enable checking of SDNode's single-use status"));
#define GET_DAGISEL_BODY …
#include "HexagonGenDAGISel.inc"
namespace llvm {
FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM,
CodeGenOptLevel OptLevel) { … }
}
HexagonDAGToDAGISelLegacy::HexagonDAGToDAGISelLegacy(HexagonTargetMachine &tm,
CodeGenOptLevel OptLevel)
: … { … }
char HexagonDAGToDAGISelLegacy::ID = …;
INITIALIZE_PASS(…)
void HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, const SDLoc &dl) { … }
MachineSDNode *HexagonDAGToDAGISel::LoadInstrForLoadIntrinsic(SDNode *IntN) { … }
SDNode *HexagonDAGToDAGISel::StoreInstrForLoadIntrinsic(MachineSDNode *LoadN,
SDNode *IntN) { … }
bool HexagonDAGToDAGISel::tryLoadOfLoadIntrinsic(LoadSDNode *N) { … }
bool HexagonDAGToDAGISel::SelectBrevLdIntrinsic(SDNode *IntN) { … }
bool HexagonDAGToDAGISel::SelectNewCircIntrinsic(SDNode *IntN) { … }
void HexagonDAGToDAGISel::SelectLoad(SDNode *N) { … }
void HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, const SDLoc &dl) { … }
void HexagonDAGToDAGISel::SelectStore(SDNode *N) { … }
void HexagonDAGToDAGISel::SelectSHL(SDNode *N) { … }
void HexagonDAGToDAGISel::SelectIntrinsicWChain(SDNode *N) { … }
void HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) { … }
void HexagonDAGToDAGISel::SelectExtractSubvector(SDNode *N) { … }
void HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) { … }
void HexagonDAGToDAGISel::SelectConstant(SDNode *N) { … }
void HexagonDAGToDAGISel::SelectFrameIndex(SDNode *N) { … }
void HexagonDAGToDAGISel::SelectAddSubCarry(SDNode *N) { … }
void HexagonDAGToDAGISel::SelectVAlign(SDNode *N) { … }
void HexagonDAGToDAGISel::SelectVAlignAddr(SDNode *N) { … }
void HexagonDAGToDAGISel::SelectTypecast(SDNode *N) { … }
void HexagonDAGToDAGISel::SelectP2D(SDNode *N) { … }
void HexagonDAGToDAGISel::SelectD2P(SDNode *N) { … }
void HexagonDAGToDAGISel::SelectV2Q(SDNode *N) { … }
void HexagonDAGToDAGISel::SelectQ2V(SDNode *N) { … }
void HexagonDAGToDAGISel::FDiv(SDNode *N) { … }
void HexagonDAGToDAGISel::FastFDiv(SDNode *N) { … }
void HexagonDAGToDAGISel::SelectFDiv(SDNode *N) { … }
void HexagonDAGToDAGISel::Select(SDNode *N) { … }
bool HexagonDAGToDAGISel::SelectInlineAsmMemoryOperand(
const SDValue &Op, InlineAsm::ConstraintCode ConstraintID,
std::vector<SDValue> &OutOps) { … }
static bool isMemOPCandidate(SDNode *I, SDNode *U) { … }
void HexagonDAGToDAGISel::ppSimplifyOrSelect0(std::vector<SDNode*> &&Nodes) { … }
void HexagonDAGToDAGISel::ppAddrReorderAddShl(std::vector<SDNode*> &&Nodes) { … }
void HexagonDAGToDAGISel::ppAddrRewriteAndSrl(std::vector<SDNode*> &&Nodes) { … }
void HexagonDAGToDAGISel::ppHoistZextI1(std::vector<SDNode*> &&Nodes) { … }
void HexagonDAGToDAGISel::PreprocessISelDAG() { … }
void HexagonDAGToDAGISel::emitFunctionEntryCode() { … }
void HexagonDAGToDAGISel::updateAligna() { … }
bool HexagonDAGToDAGISel::SelectAddrFI(SDValue &N, SDValue &R) { … }
inline bool HexagonDAGToDAGISel::SelectAddrGA(SDValue &N, SDValue &R) { … }
inline bool HexagonDAGToDAGISel::SelectAddrGP(SDValue &N, SDValue &R) { … }
inline bool HexagonDAGToDAGISel::SelectAnyImm(SDValue &N, SDValue &R) { … }
inline bool HexagonDAGToDAGISel::SelectAnyImm0(SDValue &N, SDValue &R) { … }
inline bool HexagonDAGToDAGISel::SelectAnyImm1(SDValue &N, SDValue &R) { … }
inline bool HexagonDAGToDAGISel::SelectAnyImm2(SDValue &N, SDValue &R) { … }
inline bool HexagonDAGToDAGISel::SelectAnyImm3(SDValue &N, SDValue &R) { … }
inline bool HexagonDAGToDAGISel::SelectAnyInt(SDValue &N, SDValue &R) { … }
bool HexagonDAGToDAGISel::SelectAnyImmediate(SDValue &N, SDValue &R,
Align Alignment) { … }
bool HexagonDAGToDAGISel::SelectGlobalAddress(SDValue &N, SDValue &R,
bool UseGP, Align Alignment) { … }
bool HexagonDAGToDAGISel::DetectUseSxtw(SDValue &N, SDValue &R) { … }
bool HexagonDAGToDAGISel::keepsLowBits(const SDValue &Val, unsigned NumBits,
SDValue &Src) { … }
bool HexagonDAGToDAGISel::isAlignedMemNode(const MemSDNode *N) const { … }
bool HexagonDAGToDAGISel::isSmallStackStore(const StoreSDNode *N) const { … }
bool HexagonDAGToDAGISel::isPositiveHalfWord(const SDNode *N) const { … }
bool HexagonDAGToDAGISel::hasOneUse(const SDNode *N) const { … }
static bool isOpcodeHandled(const SDNode *N) { … }
int HexagonDAGToDAGISel::getWeight(SDNode *N) { … }
int HexagonDAGToDAGISel::getHeight(SDNode *N) { … }
namespace {
struct WeightedLeaf { … };
class LeafPrioQueue { … };
}
WeightedLeaf LeafPrioQueue::findSHL(uint64_t MaxAmount) { … }
WeightedLeaf LeafPrioQueue::findMULbyConst() { … }
SDValue HexagonDAGToDAGISel::getMultiplierForSHL(SDNode *N) { … }
static unsigned getPowerOf2Factor(SDValue Val) { … }
static bool willShiftRightEliminate(SDValue V, unsigned Amount) { … }
SDValue HexagonDAGToDAGISel::factorOutPowerOf2(SDValue V, unsigned Power) { … }
static bool isTargetConstant(const SDValue &V) { … }
unsigned HexagonDAGToDAGISel::getUsesInFunction(const Value *V) { … }
SDValue HexagonDAGToDAGISel::balanceSubTree(SDNode *N, bool TopLevel) { … }
void HexagonDAGToDAGISel::rebalanceAddressTrees() { … }