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// This file defines an instruction selector for the AMDIL target. 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "AMDGPUInstrInfo.h" 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "AMDGPUISelLowering.h" // For AMDGPUISD 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "AMDGPURegisterInfo.h" 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "AMDILDevices.h" 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "AMDILUtilityFunctions.h" 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/ADT/ValueMap.h" 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/PseudoSourceValue.h" 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/SelectionDAGISel.h" 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/Support/Compiler.h" 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <list> 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <queue> 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace llvm; 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Instruction Selector Implementation 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// AMDGPUDAGToDAGISel - AMDGPU specific code to select AMDGPU machine instructions 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// //for SelectionDAG operations. 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace { 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass AMDGPUDAGToDAGISel : public SelectionDAGISel { 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Subtarget - Keep a pointer to the AMDGPU Subtarget around so that we can 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // make the right decision when generating code for different targets. 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const AMDGPUSubtarget &Subtarget; 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPUDAGToDAGISel(TargetMachine &TM); 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual ~AMDGPUDAGToDAGISel(); 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SDNode *Select(SDNode *N); 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual const char *getPassName() const; 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate: 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inline SDValue getSmallIPtrImm(unsigned Imm); 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Complex pattern selectors 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool SelectADDRParam(SDValue Addr, SDValue& R1, SDValue& R2); 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool SelectADDR(SDValue N, SDValue &R1, SDValue &R2); 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool SelectADDR64(SDValue N, SDValue &R1, SDValue &R2); 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool checkType(const Value *ptr, unsigned int addrspace); 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static const Value *getBasePointerValue(const Value *V); 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool isGlobalStore(const StoreSDNode *N); 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool isPrivateStore(const StoreSDNode *N); 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool isLocalStore(const StoreSDNode *N); 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool isRegionStore(const StoreSDNode *N); 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool isCPLoad(const LoadSDNode *N); 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool isConstantLoad(const LoadSDNode *N, int cbID); 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool isGlobalLoad(const LoadSDNode *N); 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool isPrivateLoad(const LoadSDNode *N); 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool isLocalLoad(const LoadSDNode *N); 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static bool isRegionLoad(const LoadSDNode *N); 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool SelectADDR8BitOffset(SDValue Addr, SDValue& Base, SDValue& Offset); 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool SelectADDRReg(SDValue Addr, SDValue& Base, SDValue& Offset); 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base, SDValue &Offset); 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Include the pieces autogenerated from the target description. 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "AMDGPUGenDAGISel.inc" 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // end anonymous namespace 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// createAMDGPUISelDag - This pass converts a legalized DAG into a AMDGPU-specific 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// DAG, ready for instruction scheduling. 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgFunctionPass *llvm::createAMDGPUISelDag(TargetMachine &TM 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ) { 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new AMDGPUDAGToDAGISel(TM); 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgAMDGPUDAGToDAGISel::AMDGPUDAGToDAGISel(TargetMachine &TM 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ) 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : SelectionDAGISel(TM), Subtarget(TM.getSubtarget<AMDGPUSubtarget>()) 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgAMDGPUDAGToDAGISel::~AMDGPUDAGToDAGISel() { 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSDValue AMDGPUDAGToDAGISel::getSmallIPtrImm(unsigned int Imm) { 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return CurDAG->getTargetConstant(Imm, MVT::i32); 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::SelectADDRParam( 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SDValue Addr, SDValue& R1, SDValue& R2) { 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (Addr.getOpcode() == ISD::FrameIndex) { 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R1 = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R2 = CurDAG->getTargetConstant(0, MVT::i32); 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R1 = Addr; 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R2 = CurDAG->getTargetConstant(0, MVT::i32); 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (Addr.getOpcode() == ISD::ADD) { 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R1 = Addr.getOperand(0); 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R2 = Addr.getOperand(1); 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R1 = Addr; 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R2 = CurDAG->getTargetConstant(0, MVT::i32); 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::SelectADDR(SDValue Addr, SDValue& R1, SDValue& R2) { 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (Addr.getOpcode() == ISD::TargetExternalSymbol || 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Addr.getOpcode() == ISD::TargetGlobalAddress) { 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return SelectADDRParam(Addr, R1, R2); 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::SelectADDR64(SDValue Addr, SDValue& R1, SDValue& R2) { 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (Addr.getOpcode() == ISD::TargetExternalSymbol || 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Addr.getOpcode() == ISD::TargetGlobalAddress) { 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (Addr.getOpcode() == ISD::FrameIndex) { 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R1 = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64); 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R2 = CurDAG->getTargetConstant(0, MVT::i64); 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R1 = Addr; 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R2 = CurDAG->getTargetConstant(0, MVT::i64); 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (Addr.getOpcode() == ISD::ADD) { 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R1 = Addr.getOperand(0); 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R2 = Addr.getOperand(1); 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R1 = Addr; 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org R2 = CurDAG->getTargetConstant(0, MVT::i64); 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSDNode *AMDGPUDAGToDAGISel::Select(SDNode *N) { 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int Opc = N->getOpcode(); 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (N->isMachineOpcode()) { 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; // Already selected. 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (Opc) { 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: break; 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ISD::FrameIndex: 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N)) { 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int FI = FIN->getIndex(); 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org EVT OpVT = N->getValueType(0); 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int NewOpc = AMDGPU::COPY; 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i32); 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return CurDAG->SelectNodeTo(N, NewOpc, OpVT, TFI); 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return SelectCode(N); 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::checkType(const Value *ptr, unsigned int addrspace) { 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!ptr) { 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Type *ptrType = ptr->getType(); 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return dyn_cast<PointerType>(ptrType)->getAddressSpace() == addrspace; 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst Value * AMDGPUDAGToDAGISel::getBasePointerValue(const Value *V) 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!V) { 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const Value *ret = NULL; 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ValueMap<const Value *, bool> ValueBitMap; 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::queue<const Value *, std::list<const Value *> > ValueQueue; 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ValueQueue.push(V); 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (!ValueQueue.empty()) { 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org V = ValueQueue.front(); 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ValueBitMap.find(V) == ValueBitMap.end()) { 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ValueBitMap[V] = true; 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dyn_cast<Argument>(V) && dyn_cast<PointerType>(V->getType())) { 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = V; 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (dyn_cast<GlobalVariable>(V)) { 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = V; 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (dyn_cast<Constant>(V)) { 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const ConstantExpr *CE = dyn_cast<ConstantExpr>(V); 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (CE) { 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ValueQueue.push(CE->getOperand(0)); 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (const AllocaInst *AI = dyn_cast<AllocaInst>(V)) { 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = AI; 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (const Instruction *I = dyn_cast<Instruction>(V)) { 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint32_t numOps = I->getNumOperands(); 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (uint32_t x = 0; x < numOps; ++x) { 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ValueQueue.push(I->getOperand(x)); 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // assert(0 && "Found a Value that we didn't know how to handle!"); 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ValueQueue.pop(); 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ret; 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::isGlobalStore(const StoreSDNode *N) { 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return checkType(N->getSrcValue(), AMDGPUAS::GLOBAL_ADDRESS); 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::isPrivateStore(const StoreSDNode *N) { 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (!checkType(N->getSrcValue(), AMDGPUAS::LOCAL_ADDRESS) 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !checkType(N->getSrcValue(), AMDGPUAS::GLOBAL_ADDRESS) 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !checkType(N->getSrcValue(), AMDGPUAS::REGION_ADDRESS)); 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::isLocalStore(const StoreSDNode *N) { 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return checkType(N->getSrcValue(), AMDGPUAS::LOCAL_ADDRESS); 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::isRegionStore(const StoreSDNode *N) { 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return checkType(N->getSrcValue(), AMDGPUAS::REGION_ADDRESS); 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::isConstantLoad(const LoadSDNode *N, int cbID) { 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (checkType(N->getSrcValue(), AMDGPUAS::CONSTANT_ADDRESS)) { 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineMemOperand *MMO = N->getMemOperand(); 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const Value *V = MMO->getValue(); 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const Value *BV = getBasePointerValue(V); 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (MMO 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && MMO->getValue() 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && ((V && dyn_cast<GlobalValue>(V)) 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || (BV && dyn_cast<GlobalValue>( 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org getBasePointerValue(MMO->getValue()))))) { 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return checkType(N->getSrcValue(), AMDGPUAS::PRIVATE_ADDRESS); 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::isGlobalLoad(const LoadSDNode *N) { 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return checkType(N->getSrcValue(), AMDGPUAS::GLOBAL_ADDRESS); 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::isLocalLoad(const LoadSDNode *N) { 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return checkType(N->getSrcValue(), AMDGPUAS::LOCAL_ADDRESS); 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::isRegionLoad(const LoadSDNode *N) { 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return checkType(N->getSrcValue(), AMDGPUAS::REGION_ADDRESS); 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::isCPLoad(const LoadSDNode *N) { 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MachineMemOperand *MMO = N->getMemOperand(); 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (checkType(N->getSrcValue(), AMDGPUAS::PRIVATE_ADDRESS)) { 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (MMO) { 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const Value *V = MMO->getValue(); 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(V); 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (PSV && PSV == PseudoSourceValue::getConstantPool()) { 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::isPrivateLoad(const LoadSDNode *N) { 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (checkType(N->getSrcValue(), AMDGPUAS::PRIVATE_ADDRESS)) { 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Check to make sure we are not a constant pool load or a constant load 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // that is marked as a private load 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (isCPLoad(N) || isConstantLoad(N, -1)) { 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!checkType(N->getSrcValue(), AMDGPUAS::LOCAL_ADDRESS) 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !checkType(N->getSrcValue(), AMDGPUAS::GLOBAL_ADDRESS) 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !checkType(N->getSrcValue(), AMDGPUAS::REGION_ADDRESS) 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !checkType(N->getSrcValue(), AMDGPUAS::CONSTANT_ADDRESS) 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !checkType(N->getSrcValue(), AMDGPUAS::PARAM_D_ADDRESS) 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !checkType(N->getSrcValue(), AMDGPUAS::PARAM_I_ADDRESS)) 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst char *AMDGPUDAGToDAGISel::getPassName() const { 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return "AMDGPU DAG->DAG Pattern Instruction Selection"; 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUGTMP 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#undef INT64_C 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#undef DEBUGTMP 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org///==== AMDGPU Functions ====/// 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::SelectADDR8BitOffset(SDValue Addr, SDValue& Base, 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SDValue& Offset) { 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (Addr.getOpcode() == ISD::TargetExternalSymbol || 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Addr.getOpcode() == ISD::TargetGlobalAddress) { 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (Addr.getOpcode() == ISD::ADD) { 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool Match = false; 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Find the base ptr and the offset 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned i = 0; i < Addr.getNumOperands(); i++) { 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SDValue Arg = Addr.getOperand(i); 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ConstantSDNode * OffsetNode = dyn_cast<ConstantSDNode>(Arg); 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // This arg isn't a constant so it must be the base PTR. 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!OffsetNode) { 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Base = Addr.getOperand(i); 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Check if the constant argument fits in 8-bits. The offset is in bytes 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // so we need to convert it to dwords. 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (isInt<8>(OffsetNode->getZExtValue() >> 2)) { 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Match = true; 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Offset = CurDAG->getTargetConstant(OffsetNode->getZExtValue() >> 2, 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MVT::i32); 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return Match; 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Default case, no offset 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Base = Addr; 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Offset = CurDAG->getTargetConstant(0, MVT::i32); 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::SelectADDRVTX_READ(SDValue Addr, SDValue &Base, 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SDValue &Offset) 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ConstantSDNode * IMMOffset; 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (Addr.getOpcode() == ISD::ADD 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && (IMMOffset = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && isInt<16>(IMMOffset->getZExtValue())) { 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Base = Addr.getOperand(0); 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), MVT::i32); 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // If the pointer address is constant, we can move it to the offset field. 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if ((IMMOffset = dyn_cast<ConstantSDNode>(Addr)) 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && isInt<16>(IMMOffset->getZExtValue())) { 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Base = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CurDAG->getEntryNode().getDebugLoc(), 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AMDGPU::ZERO, MVT::i32); 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), MVT::i32); 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Default case, no offset 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Base = Addr; 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Offset = CurDAG->getTargetConstant(0, MVT::i32); 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUDAGToDAGISel::SelectADDRReg(SDValue Addr, SDValue& Base, 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SDValue& Offset) { 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (Addr.getOpcode() == ISD::TargetExternalSymbol || 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Addr.getOpcode() == ISD::TargetGlobalAddress || 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Addr.getOpcode() != ISD::ADD) { 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Base = Addr.getOperand(0); 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Offset = Addr.getOperand(1); 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 396