AMDGPUISelDAGToDAG.cpp revision a2b4eb6d15a13de257319ac6231b5ab622cd02b1
1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===-- AMDILISelDAGToDAG.cpp - A dag to dag inst selector for AMDIL ------===// 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// The LLVM Compiler Infrastructure 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// This file is distributed under the University of Illinois Open Source 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// License. See LICENSE.TXT for details. 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//==-----------------------------------------------------------------------===// 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \file 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Defines an instruction selector for the AMDGPU target. 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "AMDGPUInstrInfo.h" 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "AMDGPUISelLowering.h" // For AMDGPUISD 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "AMDGPURegisterInfo.h" 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "R600InstrInfo.h" 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "SIISelLowering.h" 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/ADT/ValueMap.h" 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/Analysis/ValueTracking.h" 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineRegisterInfo.h" 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/PseudoSourceValue.h" 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/SelectionDAG.h" 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/SelectionDAGISel.h" 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/Support/Compiler.h" 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <list> 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <queue> 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace llvm; 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Instruction Selector Implementation 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace { 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// AMDGPU specific code to select AMDGPU machine instructions for 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// SelectionDAG operations. 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass AMDGPUDAGToDAGISel : public SelectionDAGISel { 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Subtarget - Keep a pointer to the AMDGPU Subtarget around so that we can 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // make the right decision when generating code for different targets. 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const AMDGPUSubtarget &Subtarget; 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPUDAGToDAGISel(TargetMachine &TM); 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ~AMDGPUDAGToDAGISel(); 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SDNode *Select(SDNode *N); 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual const char *getPassName() const; 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void PostprocessISelDAG(); 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate: 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inline SDValue getSmallIPtrImm(unsigned Imm); 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool FoldOperand(SDValue &Src, SDValue &Sel, SDValue &Neg, SDValue &Abs, 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const R600InstrInfo *TII); 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool FoldOperands(unsigned, const R600InstrInfo *, std::vector<SDValue> &); 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool FoldDotOperands(unsigned, const R600InstrInfo *, std::vector<SDValue> &); 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Complex pattern selectors 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool SelectADDRParam(SDValue Addr, SDValue& R1, SDValue& R2); 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool SelectADDR(SDValue N, SDValue &R1, SDValue &R2); 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool SelectADDR64(SDValue N, SDValue &R1, SDValue &R2); 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SDValue SimplifyI24(SDValue &Op); 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool SelectI24(SDValue Addr, SDValue &Op); 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool SelectU24(SDValue Addr, SDValue &Op); 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool checkType(const Value *ptr, unsigned int addrspace); 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool isGlobalStore(const StoreSDNode *N); 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool isPrivateStore(const StoreSDNode *N); 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool isLocalStore(const StoreSDNode *N); 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool isRegionStore(const StoreSDNode *N); 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool isCPLoad(const LoadSDNode *N) const; 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool isConstantLoad(const LoadSDNode *N, int cbID) const; 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool isGlobalLoad(const LoadSDNode *N) const; 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool isParamLoad(const LoadSDNode *N) const; 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool isPrivateLoad(const LoadSDNode *N) const; 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool isLocalLoad(const LoadSDNode *N) const; 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool isRegionLoad(const LoadSDNode *N) const; 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const TargetRegisterClass *getOperandRegClass(SDNode *N, unsigned OpNo) const; 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool SelectGlobalValueConstantOffset(SDValue Addr, SDValue& IntPtr); 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool SelectGlobalValueVariableOffset(SDValue Addr, 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SDValue &BaseReg, SDValue& Offset); 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base, SDValue &Offset); 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool SelectADDRIndirect(SDValue Addr, SDValue &Base, SDValue &Offset); 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Include the pieces autogenerated from the target description. 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "AMDGPUGenDAGISel.inc" 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // end anonymous namespace 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief This pass converts a legalized DAG into a AMDGPU-specific 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// DAG, ready for instruction scheduling. 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgFunctionPass *llvm::createAMDGPUISelDag(TargetMachine &TM 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ) { 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new AMDGPUDAGToDAGISel(TM); 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgAMDGPUDAGToDAGISel::AMDGPUDAGToDAGISel(TargetMachine &TM) 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : SelectionDAGISel(TM), Subtarget(TM.getSubtarget<AMDGPUSubtarget>()) { 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgAMDGPUDAGToDAGISel::~AMDGPUDAGToDAGISel() { 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \brief Determine the register class for \p OpNo 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// \returns The register class of the virtual register that will be used for 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// the given operand number \OpNo or NULL if the register class cannot be 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// determined. 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst TargetRegisterClass *AMDGPUDAGToDAGISel::getOperandRegClass(SDNode *N, 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned OpNo) const { 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!N->isMachineOpcode()) { 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (N->getMachineOpcode()) { 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: { 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const MCInstrDesc &Desc = TM.getInstrInfo()->get(N->getMachineOpcode()); 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned OpIdx = Desc.getNumDefs() + OpNo; 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (OpIdx >= Desc.getNumOperands()) 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int RegClass = Desc.OpInfo[OpIdx].RegClass; 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (RegClass == -1) { 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return TM.getRegisterInfo()->getRegClass(RegClass); 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case AMDGPU::REG_SEQUENCE: { 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const TargetRegisterClass *SuperRC = TM.getRegisterInfo()->getRegClass( 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cast<ConstantSDNode>(N->getOperand(0))->getZExtValue()); 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned SubRegIdx = 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dyn_cast<ConstantSDNode>(N->getOperand(OpNo + 1))->getZExtValue(); 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return TM.getRegisterInfo()->getSubClassWithSubReg(SuperRC, SubRegIdx); 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSDValue AMDGPUDAGToDAGISel::getSmallIPtrImm(unsigned int Imm) { 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return CurDAG->getTargetConstant(Imm, MVT::i32); 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::SelectADDRParam( 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SDValue Addr, SDValue& R1, SDValue& R2) { 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (Addr.getOpcode() == ISD::FrameIndex) { 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R1 = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R2 = CurDAG->getTargetConstant(0, MVT::i32); 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R1 = Addr; 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R2 = CurDAG->getTargetConstant(0, MVT::i32); 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (Addr.getOpcode() == ISD::ADD) { 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R1 = Addr.getOperand(0); 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R2 = Addr.getOperand(1); 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R1 = Addr; 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R2 = CurDAG->getTargetConstant(0, MVT::i32); 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::SelectADDR(SDValue Addr, SDValue& R1, SDValue& R2) { 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (Addr.getOpcode() == ISD::TargetExternalSymbol || 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Addr.getOpcode() == ISD::TargetGlobalAddress) { 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return SelectADDRParam(Addr, R1, R2); 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::SelectADDR64(SDValue Addr, SDValue& R1, SDValue& R2) { 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (Addr.getOpcode() == ISD::TargetExternalSymbol || 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Addr.getOpcode() == ISD::TargetGlobalAddress) { 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (Addr.getOpcode() == ISD::FrameIndex) { 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R1 = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64); 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R2 = CurDAG->getTargetConstant(0, MVT::i64); 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R1 = Addr; 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R2 = CurDAG->getTargetConstant(0, MVT::i64); 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (Addr.getOpcode() == ISD::ADD) { 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R1 = Addr.getOperand(0); 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R2 = Addr.getOperand(1); 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R1 = Addr; 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R2 = CurDAG->getTargetConstant(0, MVT::i64); 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSDNode *AMDGPUDAGToDAGISel::Select(SDNode *N) { 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int Opc = N->getOpcode(); 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (N->isMachineOpcode()) { 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org N->setNodeId(-1); 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; // Already selected. 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (Opc) { 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: break; 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ISD::BUILD_VECTOR: { 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned RegClassID; 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>(); 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const AMDGPURegisterInfo *TRI = 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static_cast<const AMDGPURegisterInfo*>(TM.getRegisterInfo()); 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const SIRegisterInfo *SIRI = 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static_cast<const SIRegisterInfo*>(TM.getRegisterInfo()); 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org EVT VT = N->getValueType(0); 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned NumVectorElts = VT.getVectorNumElements(); 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(VT.getVectorElementType().bitsEq(MVT::i32)); 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ST.getGeneration() >= AMDGPUSubtarget::SOUTHERN_ISLANDS) { 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool UseVReg = true; 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end(); 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org U != E; ++U) { 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!U->isMachineOpcode()) { 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const TargetRegisterClass *RC = getOperandRegClass(*U, U.getOperandNo()); 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!RC) { 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (SIRI->isSGPRClass(RC)) { 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UseVReg = false; 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(NumVectorElts) { 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 1: RegClassID = UseVReg ? AMDGPU::VReg_32RegClassID : 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPU::SReg_32RegClassID; 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 2: RegClassID = UseVReg ? AMDGPU::VReg_64RegClassID : 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPU::SReg_64RegClassID; 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 4: RegClassID = UseVReg ? AMDGPU::VReg_128RegClassID : 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPU::SReg_128RegClassID; 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 8: RegClassID = UseVReg ? AMDGPU::VReg_256RegClassID : 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPU::SReg_256RegClassID; 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 16: RegClassID = UseVReg ? AMDGPU::VReg_512RegClassID : 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPU::SReg_512RegClassID; 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: llvm_unreachable("Do not know how to lower this BUILD_VECTOR"); 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // BUILD_VECTOR was lowered into an IMPLICIT_DEF + 4 INSERT_SUBREG 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // that adds a 128 bits reg copy when going through TwoAddressInstructions 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // pass. We want to avoid 128 bits copies as much as possible because they 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // can't be bundled by our scheduler. 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(NumVectorElts) { 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 2: RegClassID = AMDGPU::R600_Reg64RegClassID; break; 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 4: RegClassID = AMDGPU::R600_Reg128RegClassID; break; 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: llvm_unreachable("Do not know how to lower this BUILD_VECTOR"); 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SDValue RegClass = CurDAG->getTargetConstant(RegClassID, MVT::i32); 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (NumVectorElts == 1) { 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return CurDAG->SelectNodeTo(N, AMDGPU::COPY_TO_REGCLASS, 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VT.getVectorElementType(), 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org N->getOperand(0), RegClass); 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(NumVectorElts <= 16 && "Vectors with more than 16 elements not " 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "supported yet"); 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // 16 = Max Num Vector Elements 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // 2 = 2 REG_SEQUENCE operands per element (value, subreg index) 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // 1 = Vector Register Class 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SDValue RegSeqArgs[16 * 2 + 1]; 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RegSeqArgs[0] = CurDAG->getTargetConstant(RegClassID, MVT::i32); 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool IsRegSeq = true; 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned i = 0; i < N->getNumOperands(); i++) { 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // XXX: Why is this here? 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dyn_cast<RegisterSDNode>(N->getOperand(i))) { 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org IsRegSeq = false; 279 break; 280 } 281 RegSeqArgs[1 + (2 * i)] = N->getOperand(i); 282 RegSeqArgs[1 + (2 * i) + 1] = 283 CurDAG->getTargetConstant(TRI->getSubRegFromChannel(i), MVT::i32); 284 } 285 if (!IsRegSeq) 286 break; 287 return CurDAG->SelectNodeTo(N, AMDGPU::REG_SEQUENCE, N->getVTList(), 288 RegSeqArgs, 2 * N->getNumOperands() + 1); 289 } 290 case ISD::BUILD_PAIR: { 291 SDValue RC, SubReg0, SubReg1; 292 const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>(); 293 if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) { 294 break; 295 } 296 if (N->getValueType(0) == MVT::i128) { 297 RC = CurDAG->getTargetConstant(AMDGPU::SReg_128RegClassID, MVT::i32); 298 SubReg0 = CurDAG->getTargetConstant(AMDGPU::sub0_sub1, MVT::i32); 299 SubReg1 = CurDAG->getTargetConstant(AMDGPU::sub2_sub3, MVT::i32); 300 } else if (N->getValueType(0) == MVT::i64) { 301 RC = CurDAG->getTargetConstant(AMDGPU::VSrc_64RegClassID, MVT::i32); 302 SubReg0 = CurDAG->getTargetConstant(AMDGPU::sub0, MVT::i32); 303 SubReg1 = CurDAG->getTargetConstant(AMDGPU::sub1, MVT::i32); 304 } else { 305 llvm_unreachable("Unhandled value type for BUILD_PAIR"); 306 } 307 const SDValue Ops[] = { RC, N->getOperand(0), SubReg0, 308 N->getOperand(1), SubReg1 }; 309 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, 310 SDLoc(N), N->getValueType(0), Ops); 311 } 312 case AMDGPUISD::REGISTER_LOAD: { 313 const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>(); 314 if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) 315 break; 316 SDValue Addr, Offset; 317 318 SelectADDRIndirect(N->getOperand(1), Addr, Offset); 319 const SDValue Ops[] = { 320 Addr, 321 Offset, 322 CurDAG->getTargetConstant(0, MVT::i32), 323 N->getOperand(0), 324 }; 325 return CurDAG->getMachineNode(AMDGPU::SI_RegisterLoad, SDLoc(N), 326 CurDAG->getVTList(MVT::i32, MVT::i64, MVT::Other), 327 Ops); 328 } 329 case AMDGPUISD::REGISTER_STORE: { 330 const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>(); 331 if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) 332 break; 333 SDValue Addr, Offset; 334 SelectADDRIndirect(N->getOperand(2), Addr, Offset); 335 const SDValue Ops[] = { 336 N->getOperand(1), 337 Addr, 338 Offset, 339 CurDAG->getTargetConstant(0, MVT::i32), 340 N->getOperand(0), 341 }; 342 return CurDAG->getMachineNode(AMDGPU::SI_RegisterStorePseudo, SDLoc(N), 343 CurDAG->getVTList(MVT::Other), 344 Ops); 345 } 346 } 347 return SelectCode(N); 348} 349 350 351bool AMDGPUDAGToDAGISel::checkType(const Value *ptr, unsigned int addrspace) { 352 if (!ptr) { 353 return false; 354 } 355 Type *ptrType = ptr->getType(); 356 return dyn_cast<PointerType>(ptrType)->getAddressSpace() == addrspace; 357} 358 359bool AMDGPUDAGToDAGISel::isGlobalStore(const StoreSDNode *N) { 360 return checkType(N->getSrcValue(), AMDGPUAS::GLOBAL_ADDRESS); 361} 362 363bool AMDGPUDAGToDAGISel::isPrivateStore(const StoreSDNode *N) { 364 return (!checkType(N->getSrcValue(), AMDGPUAS::LOCAL_ADDRESS) 365 && !checkType(N->getSrcValue(), AMDGPUAS::GLOBAL_ADDRESS) 366 && !checkType(N->getSrcValue(), AMDGPUAS::REGION_ADDRESS)); 367} 368 369bool AMDGPUDAGToDAGISel::isLocalStore(const StoreSDNode *N) { 370 return checkType(N->getSrcValue(), AMDGPUAS::LOCAL_ADDRESS); 371} 372 373bool AMDGPUDAGToDAGISel::isRegionStore(const StoreSDNode *N) { 374 return checkType(N->getSrcValue(), AMDGPUAS::REGION_ADDRESS); 375} 376 377bool AMDGPUDAGToDAGISel::isConstantLoad(const LoadSDNode *N, int CbId) const { 378 if (CbId == -1) { 379 return checkType(N->getSrcValue(), AMDGPUAS::CONSTANT_ADDRESS); 380 } 381 return checkType(N->getSrcValue(), AMDGPUAS::CONSTANT_BUFFER_0 + CbId); 382} 383 384bool AMDGPUDAGToDAGISel::isGlobalLoad(const LoadSDNode *N) const { 385 if (N->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS) { 386 const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>(); 387 if (ST.getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS || 388 N->getMemoryVT().bitsLT(MVT::i32)) { 389 return true; 390 } 391 } 392 return checkType(N->getSrcValue(), AMDGPUAS::GLOBAL_ADDRESS); 393} 394 395bool AMDGPUDAGToDAGISel::isParamLoad(const LoadSDNode *N) const { 396 return checkType(N->getSrcValue(), AMDGPUAS::PARAM_I_ADDRESS); 397} 398 399bool AMDGPUDAGToDAGISel::isLocalLoad(const LoadSDNode *N) const { 400 return checkType(N->getSrcValue(), AMDGPUAS::LOCAL_ADDRESS); 401} 402 403bool AMDGPUDAGToDAGISel::isRegionLoad(const LoadSDNode *N) const { 404 return checkType(N->getSrcValue(), AMDGPUAS::REGION_ADDRESS); 405} 406 407bool AMDGPUDAGToDAGISel::isCPLoad(const LoadSDNode *N) const { 408 MachineMemOperand *MMO = N->getMemOperand(); 409 if (checkType(N->getSrcValue(), AMDGPUAS::PRIVATE_ADDRESS)) { 410 if (MMO) { 411 const Value *V = MMO->getValue(); 412 const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(V); 413 if (PSV && PSV == PseudoSourceValue::getConstantPool()) { 414 return true; 415 } 416 } 417 } 418 return false; 419} 420 421bool AMDGPUDAGToDAGISel::isPrivateLoad(const LoadSDNode *N) const { 422 if (checkType(N->getSrcValue(), AMDGPUAS::PRIVATE_ADDRESS)) { 423 // Check to make sure we are not a constant pool load or a constant load 424 // that is marked as a private load 425 if (isCPLoad(N) || isConstantLoad(N, -1)) { 426 return false; 427 } 428 } 429 if (!checkType(N->getSrcValue(), AMDGPUAS::LOCAL_ADDRESS) 430 && !checkType(N->getSrcValue(), AMDGPUAS::GLOBAL_ADDRESS) 431 && !checkType(N->getSrcValue(), AMDGPUAS::REGION_ADDRESS) 432 && !checkType(N->getSrcValue(), AMDGPUAS::CONSTANT_ADDRESS) 433 && !checkType(N->getSrcValue(), AMDGPUAS::PARAM_D_ADDRESS) 434 && !checkType(N->getSrcValue(), AMDGPUAS::PARAM_I_ADDRESS)) { 435 return true; 436 } 437 return false; 438} 439 440const char *AMDGPUDAGToDAGISel::getPassName() const { 441 return "AMDGPU DAG->DAG Pattern Instruction Selection"; 442} 443 444#ifdef DEBUGTMP 445#undef INT64_C 446#endif 447#undef DEBUGTMP 448 449//===----------------------------------------------------------------------===// 450// Complex Patterns 451//===----------------------------------------------------------------------===// 452 453bool AMDGPUDAGToDAGISel::SelectGlobalValueConstantOffset(SDValue Addr, 454 SDValue& IntPtr) { 455 if (ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(Addr)) { 456 IntPtr = CurDAG->getIntPtrConstant(Cst->getZExtValue() / 4, true); 457 return true; 458 } 459 return false; 460} 461 462bool AMDGPUDAGToDAGISel::SelectGlobalValueVariableOffset(SDValue Addr, 463 SDValue& BaseReg, SDValue &Offset) { 464 if (!dyn_cast<ConstantSDNode>(Addr)) { 465 BaseReg = Addr; 466 Offset = CurDAG->getIntPtrConstant(0, true); 467 return true; 468 } 469 return false; 470} 471 472bool AMDGPUDAGToDAGISel::SelectADDRVTX_READ(SDValue Addr, SDValue &Base, 473 SDValue &Offset) { 474 ConstantSDNode * IMMOffset; 475 476 if (Addr.getOpcode() == ISD::ADD 477 && (IMMOffset = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) 478 && isInt<16>(IMMOffset->getZExtValue())) { 479 480 Base = Addr.getOperand(0); 481 Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), MVT::i32); 482 return true; 483 // If the pointer address is constant, we can move it to the offset field. 484 } else if ((IMMOffset = dyn_cast<ConstantSDNode>(Addr)) 485 && isInt<16>(IMMOffset->getZExtValue())) { 486 Base = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), 487 SDLoc(CurDAG->getEntryNode()), 488 AMDGPU::ZERO, MVT::i32); 489 Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), MVT::i32); 490 return true; 491 } 492 493 // Default case, no offset 494 Base = Addr; 495 Offset = CurDAG->getTargetConstant(0, MVT::i32); 496 return true; 497} 498 499bool AMDGPUDAGToDAGISel::SelectADDRIndirect(SDValue Addr, SDValue &Base, 500 SDValue &Offset) { 501 ConstantSDNode *C; 502 503 if ((C = dyn_cast<ConstantSDNode>(Addr))) { 504 Base = CurDAG->getRegister(AMDGPU::INDIRECT_BASE_ADDR, MVT::i32); 505 Offset = CurDAG->getTargetConstant(C->getZExtValue(), MVT::i32); 506 } else if ((Addr.getOpcode() == ISD::ADD || Addr.getOpcode() == ISD::OR) && 507 (C = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))) { 508 Base = Addr.getOperand(0); 509 Offset = CurDAG->getTargetConstant(C->getZExtValue(), MVT::i32); 510 } else { 511 Base = Addr; 512 Offset = CurDAG->getTargetConstant(0, MVT::i32); 513 } 514 515 return true; 516} 517 518SDValue AMDGPUDAGToDAGISel::SimplifyI24(SDValue &Op) { 519 APInt Demanded = APInt(32, 0x00FFFFFF); 520 APInt KnownZero, KnownOne; 521 TargetLowering::TargetLoweringOpt TLO(*CurDAG, true, true); 522 const TargetLowering *TLI = getTargetLowering(); 523 if (TLI->SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne, TLO)) { 524 CurDAG->ReplaceAllUsesWith(Op, TLO.New); 525 CurDAG->RepositionNode(Op.getNode(), TLO.New.getNode()); 526 return SimplifyI24(TLO.New); 527 } else { 528 return Op; 529 } 530} 531 532bool AMDGPUDAGToDAGISel::SelectI24(SDValue Op, SDValue &I24) { 533 534 assert(Op.getValueType() == MVT::i32); 535 536 if (CurDAG->ComputeNumSignBits(Op) == 9) { 537 I24 = SimplifyI24(Op); 538 return true; 539 } 540 return false; 541} 542 543bool AMDGPUDAGToDAGISel::SelectU24(SDValue Op, SDValue &U24) { 544 APInt KnownZero; 545 APInt KnownOne; 546 CurDAG->ComputeMaskedBits(Op, KnownZero, KnownOne); 547 548 assert (Op.getValueType() == MVT::i32); 549 550 // ANY_EXTEND and EXTLOAD operations can only be done on types smaller than 551 // i32. These smaller types are legal to use with the i24 instructions. 552 if ((KnownZero & APInt(KnownZero.getBitWidth(), 0xFF000000)) == 0xFF000000 || 553 Op.getOpcode() == ISD::ANY_EXTEND || 554 ISD::isEXTLoad(Op.getNode())) { 555 U24 = SimplifyI24(Op); 556 return true; 557 } 558 return false; 559} 560 561void AMDGPUDAGToDAGISel::PostprocessISelDAG() { 562 const AMDGPUTargetLowering& Lowering = 563 (*(const AMDGPUTargetLowering*)getTargetLowering()); 564 bool IsModified = false; 565 do { 566 IsModified = false; 567 // Go over all selected nodes and try to fold them a bit more 568 for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(), 569 E = CurDAG->allnodes_end(); I != E; ++I) { 570 571 SDNode *Node = I; 572 573 MachineSDNode *MachineNode = dyn_cast<MachineSDNode>(I); 574 if (!MachineNode) 575 continue; 576 577 SDNode *ResNode = Lowering.PostISelFolding(MachineNode, *CurDAG); 578 if (ResNode != Node) { 579 ReplaceUses(Node, ResNode); 580 IsModified = true; 581 } 582 } 583 CurDAG->RemoveDeadNodes(); 584 } while (IsModified); 585} 586