[llvm] r326390 - [NVPTX] Lower loads from global constants using ld.global.nc (aka LDG).
Justin Lebar via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 28 15:58:05 PST 2018
Author: jlebar
Date: Wed Feb 28 15:58:05 2018
New Revision: 326390
URL: http://llvm.org/viewvc/llvm-project?rev=326390&view=rev
Log:
[NVPTX] Lower loads from global constants using ld.global.nc (aka LDG).
Summary:
After D43914, loads from global variables in addrspace(1) happen with
ld.global. But since they're constants, even better would be to use
ld.global.nc, aka ldg.
Reviewers: tra
Subscribers: jholewinski, sanjoy, hiraditya, llvm-commits
Differential Revision: https://reviews.llvm.org/D43915
Added:
llvm/trunk/test/CodeGen/NVPTX/read-global-variable-constant.ll
Modified:
llvm/trunk/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp
Modified: llvm/trunk/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp?rev=326390&r1=326389&r2=326390&view=diff
==============================================================================
--- llvm/trunk/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp Wed Feb 28 15:58:05 2018
@@ -987,8 +987,10 @@ static bool canLowerToLDG(MemSDNode *N,
// We have two ways of identifying invariant loads: Loads may be explicitly
// marked as invariant, or we may infer them to be invariant.
//
- // We currently infer invariance only for kernel function pointer params that
- // are noalias (i.e. __restrict) and never written to.
+ // We currently infer invariance for loads from
+ // - constant global variables, and
+ // - kernel function pointer params that are noalias (i.e. __restrict) and
+ // never written to.
//
// TODO: Perform a more powerful invariance analysis (ideally IPO, and ideally
// not during the SelectionDAG phase).
@@ -1002,23 +1004,22 @@ static bool canLowerToLDG(MemSDNode *N,
if (N->isInvariant())
return true;
- // Load wasn't explicitly invariant. Attempt to infer invariance.
- if (!isKernelFunction(F->getFunction()))
- return false;
+ bool IsKernelFn = isKernelFunction(F->getFunction());
- // We use GetUnderlyingObjects() here instead of
- // GetUnderlyingObject() mainly because the former looks through phi
- // nodes while the latter does not. We need to look through phi
- // nodes to handle pointer induction variables.
+ // We use GetUnderlyingObjects() here instead of GetUnderlyingObject() mainly
+ // because the former looks through phi nodes while the latter does not. We
+ // need to look through phi nodes to handle pointer induction variables.
SmallVector<Value *, 8> Objs;
GetUnderlyingObjects(const_cast<Value *>(N->getMemOperand()->getValue()),
Objs, F->getDataLayout());
- for (Value *Obj : Objs) {
- auto *A = dyn_cast<const Argument>(Obj);
- if (!A || !A->onlyReadsMemory() || !A->hasNoAliasAttr()) return false;
- }
- return true;
+ return all_of(Objs, [&](Value *V) {
+ if (auto *A = dyn_cast<const Argument>(V))
+ return IsKernelFn && A->onlyReadsMemory() && A->hasNoAliasAttr();
+ if (auto *GV = dyn_cast<const GlobalVariable>(V))
+ return GV->isConstant();
+ return false;
+ });
}
bool NVPTXDAGToDAGISel::tryIntrinsicNoChain(SDNode *N) {
@@ -1632,6 +1633,7 @@ bool NVPTXDAGToDAGISel::tryLDGLDU(SDNode
switch (N->getOpcode()) {
default:
return false;
+ case ISD::LOAD:
case ISD::INTRINSIC_W_CHAIN:
if (IsLDG)
Opcode = pickOpcodeForVT(EltVT.getSimpleVT().SimpleTy,
@@ -1654,6 +1656,7 @@ bool NVPTXDAGToDAGISel::tryLDGLDU(SDNode
NVPTX::INT_PTX_LDU_GLOBAL_f32avar,
NVPTX::INT_PTX_LDU_GLOBAL_f64avar);
break;
+ case NVPTXISD::LoadV2:
case NVPTXISD::LDGV2:
Opcode = pickOpcodeForVT(EltVT.getSimpleVT().SimpleTy,
NVPTX::INT_PTX_LDG_G_v2i8_ELE_avar,
@@ -1676,6 +1679,7 @@ bool NVPTXDAGToDAGISel::tryLDGLDU(SDNode
NVPTX::INT_PTX_LDU_G_v2f32_ELE_avar,
NVPTX::INT_PTX_LDU_G_v2f64_ELE_avar);
break;
+ case NVPTXISD::LoadV4:
case NVPTXISD::LDGV4:
Opcode = pickOpcodeForVT(EltVT.getSimpleVT().SimpleTy,
NVPTX::INT_PTX_LDG_G_v4i8_ELE_avar,
Added: llvm/trunk/test/CodeGen/NVPTX/read-global-variable-constant.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/NVPTX/read-global-variable-constant.ll?rev=326390&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/NVPTX/read-global-variable-constant.ll (added)
+++ llvm/trunk/test/CodeGen/NVPTX/read-global-variable-constant.ll Wed Feb 28 15:58:05 2018
@@ -0,0 +1,29 @@
+; RUN: llc < %s -march=nvptx -mcpu=sm_35 | FileCheck %s
+
+; Check load from constant global variables. These loads should be
+; ld.global.nc (aka ldg).
+
+ at gv_float = external constant float
+ at gv_float2 = external constant <2 x float>
+ at gv_float4 = external constant <4 x float>
+
+; CHECK-LABEL: test_gv_float()
+define float @test_gv_float() {
+; CHECK: ld.global.nc.f32
+ %v = load float, float* @gv_float
+ ret float %v
+}
+
+; CHECK-LABEL: test_gv_float2()
+define <2 x float> @test_gv_float2() {
+; CHECK: ld.global.nc.v2.f32
+ %v = load <2 x float>, <2 x float>* @gv_float2
+ ret <2 x float> %v
+}
+
+; CHECK-LABEL: test_gv_float4()
+define <4 x float> @test_gv_float4() {
+; CHECK: ld.global.nc.v4.f32
+ %v = load <4 x float>, <4 x float>* @gv_float4
+ ret <4 x float> %v
+}
More information about the llvm-commits
mailing list