[llvm] r364046 - [RISCV] Add RISCV-specific TargetTransformInfo

Sam Elliott via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 21 06:36:09 PDT 2019


Author: lenary
Date: Fri Jun 21 06:36:09 2019
New Revision: 364046

URL: http://llvm.org/viewvc/llvm-project?rev=364046&view=rev
Log:
[RISCV] Add RISCV-specific TargetTransformInfo

Summary:
LLVM Allows Targets to provide information that guides optimisations
made to LLVM IR. This is done with callbacks on a TargetTransformInfo object.

This patch adds a TargetTransformInfo class for RISC-V. This will allow us to
implement RISC-V specific callbacks as they become necessary.

This commit also adds the getIntImmCost callbacks, and tests them with a simple
constant hoisting test. Our immediate costs are on the conservative side, for
the moment, but we prevent hoisting in most circumstances anyway.

Previous review was on D63007

Reviewers: asb, luismarques

Reviewed By: asb

Subscribers: ributzka, MaskRay, llvm-commits, Jim, benna, psnobl, jocewei, PkmX, rkruppe, the_o, brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, jrtc27, shiva0217, kito-cheng, niosHD, sabuasal, apazos, simoncook, johnrusso, rbar, hiraditya, mgorny

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D63433

Added:
    llvm/trunk/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
    llvm/trunk/lib/Target/RISCV/RISCVTargetTransformInfo.h
    llvm/trunk/test/Transforms/ConstantHoisting/RISCV/
    llvm/trunk/test/Transforms/ConstantHoisting/RISCV/immediates.ll
    llvm/trunk/test/Transforms/ConstantHoisting/RISCV/lit.local.cfg
Modified:
    llvm/trunk/lib/Target/RISCV/CMakeLists.txt
    llvm/trunk/lib/Target/RISCV/LLVMBuild.txt
    llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.cpp
    llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.h
    llvm/trunk/test/CodeGen/RISCV/imm-cse.ll

Modified: llvm/trunk/lib/Target/RISCV/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/CMakeLists.txt?rev=364046&r1=364045&r2=364046&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/CMakeLists.txt (original)
+++ llvm/trunk/lib/Target/RISCV/CMakeLists.txt Fri Jun 21 06:36:09 2019
@@ -27,6 +27,7 @@ add_llvm_target(RISCVCodeGen
   RISCVSubtarget.cpp
   RISCVTargetMachine.cpp
   RISCVTargetObjectFile.cpp
+  RISCVTargetTransformInfo.cpp
   )
 
 add_subdirectory(AsmParser)

Modified: llvm/trunk/lib/Target/RISCV/LLVMBuild.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/LLVMBuild.txt?rev=364046&r1=364045&r2=364046&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/LLVMBuild.txt (original)
+++ llvm/trunk/lib/Target/RISCV/LLVMBuild.txt Fri Jun 21 06:36:09 2019
@@ -29,6 +29,6 @@ has_disassembler = 1
 type = Library
 name = RISCVCodeGen
 parent = RISCV
-required_libraries = AsmPrinter Core CodeGen MC RISCVDesc
+required_libraries = Analysis AsmPrinter Core CodeGen MC RISCVDesc
   RISCVInfo RISCVUtils SelectionDAG Support Target
 add_to_library_groups = RISCV

Modified: llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.cpp?rev=364046&r1=364045&r2=364046&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.cpp Fri Jun 21 06:36:09 2019
@@ -10,11 +10,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "RISCV.h"
 #include "RISCVTargetMachine.h"
+#include "RISCV.h"
 #include "RISCVTargetObjectFile.h"
+#include "RISCVTargetTransformInfo.h"
 #include "TargetInfo/RISCVTargetInfo.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
@@ -61,6 +63,11 @@ RISCVTargetMachine::RISCVTargetMachine(c
   initAsmInfo();
 }
 
+TargetTransformInfo
+RISCVTargetMachine::getTargetTransformInfo(const Function &F) {
+  return TargetTransformInfo(RISCVTTIImpl(this, F));
+}
+
 namespace {
 class RISCVPassConfig : public TargetPassConfig {
 public:

Modified: llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.h?rev=364046&r1=364045&r2=364046&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.h (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.h Fri Jun 21 06:36:09 2019
@@ -39,6 +39,8 @@ public:
   TargetLoweringObjectFile *getObjFileLowering() const override {
     return TLOF.get();
   }
+
+  TargetTransformInfo getTargetTransformInfo(const Function &F) override;
 };
 }
 

Added: llvm/trunk/lib/Target/RISCV/RISCVTargetTransformInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVTargetTransformInfo.cpp?rev=364046&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVTargetTransformInfo.cpp (added)
+++ llvm/trunk/lib/Target/RISCV/RISCVTargetTransformInfo.cpp Fri Jun 21 06:36:09 2019
@@ -0,0 +1,90 @@
+//===-- RISCVTargetTransformInfo.cpp - RISC-V specific TTI ----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "RISCVTargetTransformInfo.h"
+#include "Utils/RISCVMatInt.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/CodeGen/BasicTTIImpl.h"
+#include "llvm/CodeGen/TargetLowering.h"
+using namespace llvm;
+
+#define DEBUG_TYPE "riscvtti"
+
+int RISCVTTIImpl::getIntImmCost(const APInt &Imm, Type *Ty) {
+  assert(Ty->isIntegerTy() &&
+         "getIntImmCost can only estimate cost of materialising integers");
+
+  // We have a Zero register, so 0 is always free.
+  if (Imm == 0)
+    return TTI::TCC_Free;
+
+  // Otherwise, we check how many instructions it will take to materialise.
+  const DataLayout &DL = getDataLayout();
+  return RISCVMatInt::getIntMatCost(Imm, DL.getTypeSizeInBits(Ty),
+                                    getST()->is64Bit());
+}
+
+int RISCVTTIImpl::getIntImmCost(unsigned Opcode, unsigned Idx, const APInt &Imm,
+                                Type *Ty) {
+  assert(Ty->isIntegerTy() &&
+         "getIntImmCost can only estimate cost of materialising integers");
+
+  // We have a Zero register, so 0 is always free.
+  if (Imm == 0)
+    return TTI::TCC_Free;
+
+  // Some instructions in RISC-V can take a 12-bit immediate. Some of these are
+  // commutative, in others the immediate comes from a specific argument index.
+  bool Takes12BitImm = false;
+  unsigned ImmArgIdx = ~0U;
+
+  switch (Opcode) {
+  case Instruction::GetElementPtr:
+    // Never hoist any arguments to a GetElementPtr. CodeGenPrepare will
+    // split up large offsets in GEP into better parts than ConstantHoisting
+    // can.
+    return TTI::TCC_Free;
+  case Instruction::Add:
+  case Instruction::And:
+  case Instruction::Or:
+  case Instruction::Xor:
+  case Instruction::Mul:
+    Takes12BitImm = true;
+    break;
+  case Instruction::Sub:
+  case Instruction::Shl:
+  case Instruction::LShr:
+  case Instruction::AShr:
+    Takes12BitImm = true;
+    ImmArgIdx = 1;
+    break;
+  default:
+    break;
+  }
+
+  if (Takes12BitImm) {
+    // Check immediate is the correct argument...
+    if (Instruction::isCommutative(Opcode) || Idx == ImmArgIdx) {
+      // ... and fits into the 12-bit immediate.
+      if (getTLI()->isLegalAddImmediate(Imm.getSExtValue()))
+        return TTI::TCC_Free;
+    }
+
+    // Otherwise, use the full materialisation cost.
+    return getIntImmCost(Imm, Ty);
+  }
+
+  // By default, prevent hoisting.
+  return TTI::TCC_Free;
+}
+
+int RISCVTTIImpl::getIntImmCost(Intrinsic::ID IID, unsigned Idx,
+                                const APInt &Imm, Type *Ty) {
+  // Prevent hoisting in unknown cases.
+  return TTI::TCC_Free;
+}

Added: llvm/trunk/lib/Target/RISCV/RISCVTargetTransformInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVTargetTransformInfo.h?rev=364046&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVTargetTransformInfo.h (added)
+++ llvm/trunk/lib/Target/RISCV/RISCVTargetTransformInfo.h Fri Jun 21 06:36:09 2019
@@ -0,0 +1,52 @@
+//===- RISCVTargetTransformInfo.h - RISC-V specific TTI ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file defines a TargetTransformInfo::Concept conforming object specific
+/// to the RISC-V target machine. It uses the target's detailed information to
+/// provide more precise answers to certain TTI queries, while letting the
+/// target independent and default TTI implementations handle the rest.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_RISCV_RISCVTARGETTRANSFORMINFO_H
+#define LLVM_LIB_TARGET_RISCV_RISCVTARGETTRANSFORMINFO_H
+
+#include "RISCVSubtarget.h"
+#include "RISCVTargetMachine.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/CodeGen/BasicTTIImpl.h"
+#include "llvm/IR/Function.h"
+
+namespace llvm {
+
+class RISCVTTIImpl : public BasicTTIImplBase<RISCVTTIImpl> {
+  using BaseT = BasicTTIImplBase<RISCVTTIImpl>;
+  using TTI = TargetTransformInfo;
+
+  friend BaseT;
+
+  const RISCVSubtarget *ST;
+  const RISCVTargetLowering *TLI;
+
+  const RISCVSubtarget *getST() const { return ST; }
+  const RISCVTargetLowering *getTLI() const { return TLI; }
+
+public:
+  explicit RISCVTTIImpl(const RISCVTargetMachine *TM, const Function &F)
+      : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)),
+        TLI(ST->getTargetLowering()) {}
+
+  int getIntImmCost(const APInt &Imm, Type *Ty);
+  int getIntImmCost(unsigned Opcode, unsigned Idx, const APInt &Imm, Type *Ty);
+  int getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
+                    Type *Ty);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_RISCV_RISCVTARGETTRANSFORMINFO_H
\ No newline at end of file

Modified: llvm/trunk/test/CodeGen/RISCV/imm-cse.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/imm-cse.ll?rev=364046&r1=364045&r2=364046&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/imm-cse.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/imm-cse.ll Fri Jun 21 06:36:09 2019
@@ -11,19 +11,19 @@ define void @imm32_cse() nounwind {
 ; RV32I-LABEL: imm32_cse:
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    lui a0, 1
-; RV32I-NEXT:    addi a1, a0, 1
-; RV32I-NEXT:    lui a2, %hi(src)
-; RV32I-NEXT:    lw a3, %lo(src)(a2)
-; RV32I-NEXT:    add a1, a3, a1
+; RV32I-NEXT:    addi a0, a0, 1
+; RV32I-NEXT:    lui a1, %hi(src)
+; RV32I-NEXT:    lw a2, %lo(src)(a1)
+; RV32I-NEXT:    add a2, a2, a0
 ; RV32I-NEXT:    lui a3, %hi(dst)
-; RV32I-NEXT:    sw a1, %lo(dst)(a3)
-; RV32I-NEXT:    addi a1, a0, 2
-; RV32I-NEXT:    lw a4, %lo(src)(a2)
-; RV32I-NEXT:    add a1, a4, a1
-; RV32I-NEXT:    sw a1, %lo(dst)(a3)
-; RV32I-NEXT:    addi a0, a0, 3
-; RV32I-NEXT:    lw a1, %lo(src)(a2)
+; RV32I-NEXT:    sw a2, %lo(dst)(a3)
+; RV32I-NEXT:    lw a2, %lo(src)(a1)
+; RV32I-NEXT:    add a2, a2, a0
+; RV32I-NEXT:    addi a2, a2, 1
+; RV32I-NEXT:    sw a2, %lo(dst)(a3)
+; RV32I-NEXT:    lw a1, %lo(src)(a1)
 ; RV32I-NEXT:    add a0, a1, a0
+; RV32I-NEXT:    addi a0, a0, 2
 ; RV32I-NEXT:    sw a0, %lo(dst)(a3)
 ; RV32I-NEXT:    ret
   %1 = load volatile i32, i32* @src

Added: llvm/trunk/test/Transforms/ConstantHoisting/RISCV/immediates.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ConstantHoisting/RISCV/immediates.ll?rev=364046&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/ConstantHoisting/RISCV/immediates.ll (added)
+++ llvm/trunk/test/Transforms/ConstantHoisting/RISCV/immediates.ll Fri Jun 21 06:36:09 2019
@@ -0,0 +1,29 @@
+; RUN: opt -mtriple=riscv32-unknown-elf -S -consthoist < %s | FileCheck %s
+; RUN: opt -mtriple=riscv64-unknown-elf -S -consthoist < %s | FileCheck %s
+
+; Check that we don't hoist immediates with small values.
+define i64 @test1(i64 %a) nounwind {
+; CHECK-LABEL: test1
+; CHECK-NOT: %const = bitcast i64 2 to i64
+  %1 = mul i64 %a, 2
+  %2 = add i64 %1, 2
+  ret i64 %2
+}
+
+; Check that we don't hoist immediates with small values.
+define i64 @test2(i64 %a) nounwind {
+; CHECK-LABEL: test2
+; CHECK-NOT: %const = bitcast i64 2047 to i64
+  %1 = mul i64 %a, 2047
+  %2 = add i64 %1, 2047
+  ret i64 %2
+}
+
+; Check that we hoist immediates with large values.
+define i64 @test3(i64 %a) nounwind {
+; CHECK-LABEL: test3
+; CHECK: %const = bitcast i64 32767 to i64
+  %1 = mul i64 %a, 32767
+  %2 = add i64 %1, 32767
+  ret i64 %2
+}
\ No newline at end of file

Added: llvm/trunk/test/Transforms/ConstantHoisting/RISCV/lit.local.cfg
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ConstantHoisting/RISCV/lit.local.cfg?rev=364046&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/ConstantHoisting/RISCV/lit.local.cfg (added)
+++ llvm/trunk/test/Transforms/ConstantHoisting/RISCV/lit.local.cfg Fri Jun 21 06:36:09 2019
@@ -0,0 +1,2 @@
+if not 'RISCV' in config.root.targets:
+    config.unsupported = True
\ No newline at end of file




More information about the llvm-commits mailing list