mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
62272f1feb
Summary: DAGCombine will normally turn a `(shl (add x, c1), c2)` into `(add (shl x, c2), c1 << c2)`, where `c1` and `c2` are constants. This can be prevented by a callback in TargetLowering. On RISC-V, materialising the constant `c1 << c2` can be more expensive than materialising `c1`, because materialising the former may take more instructions, and may use a register, where materialising the latter would not. This patch implements the hook in RISCVTargetLowering to prevent this transform, in the cases where: - `c1` fits into the immediate field in an `addi` instruction. - `c1` takes fewer instructions to materialise than `c1 << c2`. In future, DAGCombine could do the check to see whether `c1` fits into an add immediate, which might simplify more targets hooks than just RISC-V. Reviewers: asb, luismarques, efriedma Reviewed By: asb Subscribers: xbolva00, lebedev.ri, craig.topper, lewis-revill, Jim, hiraditya, rbar, johnrusso, simoncook, apazos, sabuasal, niosHD, kito-cheng, shiva0217, jrtc27, zzheng, edward-jones, rogfer01, MartinMosbeck, brucehoult, the_o, rkruppe, PkmX, jocewei, psnobl, benna, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D62857 llvm-svn: 363736
45 lines
1.6 KiB
C++
45 lines
1.6 KiB
C++
//===- RISCVMatInt.h - Immediate materialisation ---------------*- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_LIB_TARGET_RISCV_MATINT_H
|
|
#define LLVM_LIB_TARGET_RISCV_MATINT_H
|
|
|
|
#include "llvm/ADT/APInt.h"
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "llvm/Support/MachineValueType.h"
|
|
#include <cstdint>
|
|
|
|
namespace llvm {
|
|
|
|
namespace RISCVMatInt {
|
|
struct Inst {
|
|
unsigned Opc;
|
|
int64_t Imm;
|
|
|
|
Inst(unsigned Opc, int64_t Imm) : Opc(Opc), Imm(Imm) {}
|
|
};
|
|
using InstSeq = SmallVector<Inst, 8>;
|
|
|
|
// Helper to generate an instruction sequence that will materialise the given
|
|
// immediate value into a register. A sequence of instructions represented by
|
|
// a simple struct produced rather than directly emitting the instructions in
|
|
// order to allow this helper to be used from both the MC layer and during
|
|
// instruction selection.
|
|
void generateInstSeq(int64_t Val, bool IsRV64, InstSeq &Res);
|
|
|
|
// Helper to estimate the number of instructions required to materialise the
|
|
// given immediate value into a register. This estimate does not account for
|
|
// `Val` possibly fitting into an immediate, and so may over-estimate.
|
|
//
|
|
// This will attempt to produce instructions to materialise `Val` as an
|
|
// `Size`-bit immediate. `IsRV64` should match the target architecture.
|
|
int getIntMatCost(const APInt &Val, unsigned Size, bool IsRV64);
|
|
} // namespace RISCVMatInt
|
|
} // namespace llvm
|
|
#endif
|