CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
258 lines
9.3 KiB
TableGen
258 lines
9.3 KiB
TableGen
//==----- RISCVMacroFusion.td - Macro Fusion Definitions -----*- tablegen -*-=//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// ===---------------------------------------------------------------------===//
|
|
// The following definitions describe the macro fusion predicators.
|
|
|
|
// Fuse LUI followed by ADDI or ADDIW:
|
|
// rd = imm[31:0] which decomposes to
|
|
// lui rd, imm[31:12]
|
|
// addi(w) rd, rd, imm[11:0]
|
|
def TuneLUIADDIFusion
|
|
: SimpleFusion<"lui-addi", "HasLUIADDIFusion",
|
|
"Enable LUI+ADDI macro fusion",
|
|
CheckOpcode<[LUI]>,
|
|
CheckOpcode<[ADDI, ADDIW]>>;
|
|
|
|
// Fuse AUIPC followed by ADDI:
|
|
// auipc rd, imm20
|
|
// addi rd, rd, imm12
|
|
def TuneAUIPCADDIFusion
|
|
: SimpleFusion<"auipc-addi", "HasAUIPCADDIFusion",
|
|
"Enable AUIPC+ADDI macrofusion",
|
|
CheckOpcode<[AUIPC]>,
|
|
CheckOpcode<[ADDI]>>;
|
|
|
|
// Fuse zero extension of halfword:
|
|
// slli rd, rs1, 48
|
|
// srli rd, rd, 48
|
|
def TuneZExtHFusion
|
|
: SimpleFusion<"zexth", "HasZExtHFusion",
|
|
"Enable SLLI+SRLI to be fused to zero extension of halfword",
|
|
CheckAll<[
|
|
CheckOpcode<[SLLI]>,
|
|
CheckIsImmOperand<2>,
|
|
CheckImmOperand<2, 48>
|
|
]>,
|
|
CheckAll<[
|
|
CheckOpcode<[SRLI]>,
|
|
CheckIsImmOperand<2>,
|
|
CheckImmOperand<2, 48>
|
|
]>>;
|
|
|
|
// Fuse zero extension of word:
|
|
// slli rd, rs1, 32
|
|
// srli rd, rd, 32
|
|
def TuneZExtWFusion
|
|
: SimpleFusion<"zextw", "HasZExtWFusion",
|
|
"Enable SLLI+SRLI to be fused to zero extension of word",
|
|
CheckAll<[
|
|
CheckOpcode<[SLLI]>,
|
|
CheckIsImmOperand<2>,
|
|
CheckImmOperand<2, 32>
|
|
]>,
|
|
CheckAll<[
|
|
CheckOpcode<[SRLI]>,
|
|
CheckIsImmOperand<2>,
|
|
CheckImmOperand<2, 32>
|
|
]>>;
|
|
|
|
// Fuse shifted zero extension of word:
|
|
// slli rd, rs1, 32
|
|
// srli rd, rd, x
|
|
// where 0 <= x < 32
|
|
def TuneShiftedZExtWFusion
|
|
: SimpleFusion<"shifted-zextw", "HasShiftedZExtWFusion",
|
|
"Enable SLLI+SRLI to be fused when computing (shifted) word zero extension",
|
|
CheckAll<[
|
|
CheckOpcode<[SLLI]>,
|
|
CheckIsImmOperand<2>,
|
|
CheckImmOperand<2, 32>
|
|
]>,
|
|
CheckAll<[
|
|
CheckOpcode<[SRLI]>,
|
|
CheckIsImmOperand<2>,
|
|
CheckImmOperandRange<2, 0, 31>
|
|
]>>;
|
|
|
|
// Fuse load with add:
|
|
// add rd, rs1, rs2
|
|
// ld rd, 0(rd)
|
|
def TuneLDADDFusion
|
|
: SimpleFusion<"ld-add", "HasLDADDFusion", "Enable LD+ADD macrofusion",
|
|
CheckOpcode<[ADD]>,
|
|
CheckAll<[
|
|
CheckOpcode<[LD]>,
|
|
CheckIsImmOperand<2>,
|
|
CheckImmOperand<2, 0>
|
|
]>>;
|
|
|
|
defvar Load = [LB, LH, LW, LD, LBU, LHU, LWU];
|
|
defvar LoadStore = [LB, LBU, LH, LHU, LW, LWU, LD,
|
|
FLH, FLW, FLD,
|
|
SB, SH, SW, SD,
|
|
FSH, FSW, FSD];
|
|
defvar LogicOp = [AND, OR, XOR];
|
|
defvar LogicImmOp = [ANDI, ORI, XORI];
|
|
defvar ShiftLeft = [SLLI, SLLIW];
|
|
defvar ShiftRight = [SRLI, SRLIW, SRAI, SRAIW];
|
|
|
|
// Fuse add(.uw) followed by a load (lb, lh, lw, ld, lbu, lhu, lwu):
|
|
// add(.uw) rd, rs1, rs2
|
|
// load rd, imm12(rd)
|
|
def TuneADDLoadFusion
|
|
: SimpleFusion<"add-load", "HasADDLoadFusion", "Enable ADD(.UW) + load macrofusion",
|
|
CheckOpcode<[ADD, ADD_UW]>,
|
|
CheckOpcode<Load>>;
|
|
|
|
// Fuse AUIPC followed by by a load (lb, lh, lw, ld, lbu, lhu, lwu)
|
|
// auipc rd, imm20
|
|
// load rd, imm12(rd)
|
|
def TuneAUIPCLoadFusion
|
|
: SimpleFusion<"auipc-load", "HasAUIPCLoadFusion",
|
|
"Enable AUIPC + load macrofusion",
|
|
CheckOpcode<[AUIPC]>,
|
|
CheckOpcode<Load>>;
|
|
|
|
// Fuse LUI followed by a load (lb, lh, lw, ld, lbu, lhu, lwu)
|
|
// lui rd, imm[31:12]
|
|
// load rd, imm12(rd)
|
|
def TuneLUILoadFusion
|
|
: SimpleFusion<"lui-load", "HasLUILoadFusion",
|
|
"Enable LUI + load macrofusion",
|
|
CheckOpcode<[LUI]>,
|
|
CheckOpcode<Load>>;
|
|
|
|
// Bitfield extract fusion: similar to TuneShiftedZExtWFusion
|
|
// but without the immediate restriction
|
|
// slli rd, rs1, imm12
|
|
// srli rd, rd, imm12
|
|
def TuneBFExtFusion
|
|
: SimpleFusion<"bfext", "HasBFExtFusion",
|
|
"Enable SLLI+SRLI (bitfield extract) macrofusion",
|
|
CheckOpcode<[SLLI]>,
|
|
CheckOpcode<[SRLI]>>;
|
|
|
|
// Fuse ADDI followed by a load (lb, lh, lw, ld, lbu, lhu, lwu)
|
|
// addi rd, rs1, imm12
|
|
// load rd, imm12(rd)
|
|
def TuneADDILoadFusion
|
|
: SimpleFusion<"addi-load", "HasADDILoadFusion",
|
|
"Enable ADDI + load macrofusion",
|
|
CheckOpcode<[ADDI]>,
|
|
CheckOpcode<Load>>;
|
|
|
|
// Fuse shXadd(.uw) followed by a load (lb, lh, lw, ld, lbu, lhu, lwu)
|
|
// shXadd(.uw) rd, rs1, rs2
|
|
// load rd, imm12(rd)
|
|
def TuneSHXADDLoadFusion
|
|
: SimpleFusion<"shxadd-load", "HasSHXADDLoadFusion",
|
|
"Enable SH(1|2|3)ADD(.UW) + load macrofusion",
|
|
CheckOpcode<[SH1ADD, SH2ADD, SH3ADD, SH1ADD_UW, SH2ADD_UW, SH3ADD_UW]>,
|
|
CheckOpcode<Load>>;
|
|
|
|
// Fuse logic operation followed by another logic operation:
|
|
// and/or/xor rd, rs1, rs2
|
|
// and/or/xor rd, rd, rs3
|
|
let IsCommutable = 1 in
|
|
def TuneFusionLogicRegReg
|
|
: SimpleFusion<"logic-reg-reg", "HasFusionLogicRegReg",
|
|
"Enable AND/OR/XOR+AND/OR/XOR macrofusion",
|
|
CheckOpcode<LogicOp>,
|
|
CheckOpcode<LogicOp>>;
|
|
|
|
// Fuse logic operation followed by logic immediate operation:
|
|
// and/or/xor rd, rs1, rs2
|
|
// andi/ori/xori rd, rd, imm
|
|
def TuneFusionLogicRegImm
|
|
: SimpleFusion<"logic-reg-imm", "HasFusionLogicRegImm",
|
|
"Enable AND/OR/XOR+ANDI/ORI/XORI macrofusion",
|
|
CheckOpcode<LogicOp>,
|
|
CheckOpcode<LogicImmOp>>;
|
|
|
|
// Fuse logic immediate operation followed by logic operation:
|
|
// andi/ori/xori rd, rs1, imm
|
|
// and/or/xor rd, rd, rs2
|
|
let IsCommutable = 1 in
|
|
def TuneFusionLogicImmReg
|
|
: SimpleFusion<"logic-imm-reg", "HasFusionLogicImmReg",
|
|
"Enable ANDI/ORI/XORI+AND/OR/XOR macrofusion",
|
|
CheckOpcode<LogicImmOp>,
|
|
CheckOpcode<LogicOp>>;
|
|
|
|
// Fuse multiply followed by add:
|
|
// mul(w) rd, rs1, rs2
|
|
// add(w) rd, rd, rs3
|
|
def TuneFusionMulAdd
|
|
: SimpleFusion<"mul-add", "HasFusionMulAdd",
|
|
"Enable MUL+ADD macrofusion",
|
|
CheckOpcode<[MUL, MULW]>,
|
|
CheckOpcode<[ADD, ADDW]>,
|
|
epilog = [
|
|
// Check that both instructions have the same width
|
|
FusionPredicateWithCode<[{
|
|
if ((FirstMI->getDesc().TSFlags & RISCVII::IsSignExtendingOpWMask) !=
|
|
(SecondMI.getDesc().TSFlags & RISCVII::IsSignExtendingOpWMask))
|
|
return false;
|
|
}]>,
|
|
SecondFusionPredicateWithMCInstPredicate<
|
|
CheckNot<CheckSameRegOperand<0, 2>>
|
|
>
|
|
]>;
|
|
|
|
// Fuse add with load or store with zero offset:
|
|
// add rd, rs1, rs2
|
|
// load/store rt, 0(rd)
|
|
def TuneFusionAddMem
|
|
: Fusion<"add-mem", "HasFusionAddMem",
|
|
"Enable ADD+LOAD/STORE macrofusion",
|
|
[
|
|
SecondFusionPredicateWithMCInstPredicate<
|
|
CheckAll<[
|
|
CheckOpcode<LoadStore>,
|
|
CheckIsImmOperand<2>,
|
|
CheckImmOperand<2, 0>
|
|
]>
|
|
>,
|
|
WildcardTrue,
|
|
FirstFusionPredicateWithMCInstPredicate<
|
|
CheckAll<[
|
|
CheckOpcode<[ADD]>,
|
|
CheckNot<CheckSameRegOperand<0, 1>>,
|
|
CheckNot<CheckSameRegOperand<0, 2>>
|
|
]>
|
|
>,
|
|
TieReg<0, 1>
|
|
]>;
|
|
|
|
// Fuse shift left followed by shift right for bit extraction:
|
|
// slli(w) rd, rs1, imm1
|
|
// srli(w)/srai(w) rd, rd, imm2
|
|
// where imm1 <= imm2
|
|
def TuneFusionShiftBitExtract
|
|
: SimpleFusion<"shift-bit-extract", "HasFusionShiftBitExtract",
|
|
"Enable SLLI+SRLI/SRAI macrofusion",
|
|
CheckOpcode<ShiftLeft>,
|
|
CheckOpcode<ShiftRight>,
|
|
epilog = [
|
|
// Check that both instructions have the same width
|
|
FusionPredicateWithCode<[{
|
|
if ((FirstMI->getDesc().TSFlags & RISCVII::IsSignExtendingOpWMask) !=
|
|
(SecondMI.getDesc().TSFlags & RISCVII::IsSignExtendingOpWMask))
|
|
return false;
|
|
}]>,
|
|
// Check that FirstMI's immediate <= SecondMI's immediate
|
|
FusionPredicateWithCode<[{
|
|
if (!(FirstMI->getOperand(2).isImm() &&
|
|
SecondMI.getOperand(2).isImm() &&
|
|
FirstMI->getOperand(2).getImm() <=
|
|
SecondMI.getOperand(2).getImm()))
|
|
return false;
|
|
}]>,
|
|
]>;
|