Skip to content

Commit

Permalink
[HEXAGON] Utilize new mask instruction
Browse files Browse the repository at this point in the history
Co-authored-by: Harsha Jagasia <[email protected]>
Co-authored-by: Krzysztof Parzyszek <[email protected]>
  • Loading branch information
3 people committed Jul 29, 2024
1 parent a8e1c3e commit 025e2ea
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 0 deletions.
1 change: 1 addition & 0 deletions llvm/lib/Target/Hexagon/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ add_llvm_target(HexagonCodeGen
HexagonLoopIdiomRecognition.cpp
HexagonMachineFunctionInfo.cpp
HexagonMachineScheduler.cpp
HexagonMask.cpp
HexagonMCInstLower.cpp
HexagonNewValueJump.cpp
HexagonOptAddrMode.cpp
Expand Down
110 changes: 110 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonMask.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
//===-- HexagonMask.cpp - replace const ext tfri with mask ------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "mask"

#include "HexagonMachineFunctionInfo.h"
#include "HexagonSubtarget.h"
#include "HexagonTargetMachine.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetMachine.h"

using namespace llvm;

namespace llvm {
FunctionPass *createHexagonMask();
void initializeHexagonMaskPass(PassRegistry &);

class HexagonMask : public MachineFunctionPass {
public:
static char ID;
HexagonMask() : MachineFunctionPass(ID) {
PassRegistry &Registry = *PassRegistry::getPassRegistry();
initializeHexagonMaskPass(Registry);
}

StringRef getPassName() const override {
return "Hexagon replace const ext tfri with mask";
}
bool runOnMachineFunction(MachineFunction &MF) override;

private:
const HexagonInstrInfo *HII;
void replaceConstExtTransferImmWithMask(MachineFunction &MF);
};

char HexagonMask::ID = 0;

void HexagonMask::replaceConstExtTransferImmWithMask(MachineFunction &MF) {
for (auto &MBB : MF) {
for (auto &MI : llvm::make_early_inc_range(MBB)) {
if (MI.getOpcode() != Hexagon::A2_tfrsi)
continue;

const MachineOperand &Op0 = MI.getOperand(0);
const MachineOperand &Op1 = MI.getOperand(1);
if (!Op1.isImm())
continue;
int32_t V = Op1.getImm();
if (isInt<16>(V))
continue;

unsigned Idx, Len;
if (!isShiftedMask_32(V, Idx, Len))
continue;
if (!isUInt<5>(Idx) || !isUInt<5>(Len))
continue;

BuildMI(MBB, MI, MI.getDebugLoc(), HII->get(Hexagon::S2_mask),
Op0.getReg())
.addImm(Len)
.addImm(Idx);
MBB.erase(MI);
}
}
}

bool HexagonMask::runOnMachineFunction(MachineFunction &MF) {
auto &HST = MF.getSubtarget<HexagonSubtarget>();
HII = HST.getInstrInfo();
const Function &F = MF.getFunction();

if (!F.hasFnAttribute(Attribute::OptimizeForSize))
return false;
// The mask instruction available in v66 can be used to generate values in
// registers using 2 immediates Eg. to form 0x07fffffc in R0, you would write
// "R0 = mask(#25,#2)" Since it is a single-word instruction, it takes less
// code size than a constant-extended transfer at Os
replaceConstExtTransferImmWithMask(MF);

return true;
}

} // namespace llvm

//===----------------------------------------------------------------------===//
// Public Constructor Functions
//===----------------------------------------------------------------------===//

INITIALIZE_PASS(HexagonMask, "hexagon-mask", "Hexagon mask", false, false)

FunctionPass *llvm::createHexagonMask() { return new HexagonMask(); }
11 changes: 11 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ static cl::opt<bool>
DisableHCP("disable-hcp", cl::Hidden,
cl::desc("Disable Hexagon constant propagation"));

static cl::opt<bool> DisableHexagonMask(
"disable-mask", cl::Hidden,
cl::desc("Disable Hexagon specific Mask generation pass"));

static cl::opt<bool> DisableStoreWidening("disable-store-widen", cl::Hidden,
cl::init(false),
cl::desc("Disable store widening"));
Expand Down Expand Up @@ -180,6 +184,8 @@ void initializeHexagonGenMuxPass(PassRegistry &);
void initializeHexagonHardwareLoopsPass(PassRegistry &);
void initializeHexagonLoopIdiomRecognizeLegacyPassPass(PassRegistry &);
void initializeHexagonLoopAlignPass(PassRegistry &);
void initializeHexagonMaskPass(PassRegistry &);
void initializeHexagonMergeActivateWeightPass(PassRegistry &);
void initializeHexagonNewValueJumpPass(PassRegistry &);
void initializeHexagonOptAddrModePass(PassRegistry &);
void initializeHexagonPacketizerPass(PassRegistry &);
Expand Down Expand Up @@ -213,6 +219,8 @@ FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM,
CodeGenOptLevel OptLevel);
FunctionPass *createHexagonLoopAlign();
FunctionPass *createHexagonLoopRescheduling();
FunctionPass *createHexagonMask();
FunctionPass *createHexagonMergeActivateWeight();
FunctionPass *createHexagonNewValueJump();
FunctionPass *createHexagonOptAddrMode();
FunctionPass *createHexagonOptimizeSZextends();
Expand Down Expand Up @@ -474,10 +482,13 @@ void HexagonPassConfig::addPostRegAlloc() {
}

void HexagonPassConfig::addPreSched2() {
bool NoOpt = (getOptLevel() == CodeGenOptLevel::None);
addPass(createHexagonCopyToCombine());
if (getOptLevel() != CodeGenOptLevel::None)
addPass(&IfConverterID);
addPass(createHexagonSplitConst32AndConst64());
if (!NoOpt && !DisableHexagonMask)
addPass(createHexagonMask());
}

void HexagonPassConfig::addPreEmitPass() {
Expand Down
17 changes: 17 additions & 0 deletions llvm/test/CodeGen/Hexagon/mask.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
; RUN: llc -mtriple=hexagon -mcpu=hexagonv73 < %s | FileCheck %s

target triple = "hexagon"

; CHECK-LABEL: test1:
; CHECK: r0 = mask(#25,#2)
; Function Attrs: optsize
define i32 @test1() #1 {
entry:
%0 = call i32 @llvm.hexagon.A2.tfr(i32 134217724)
ret i32 %0
}

declare i32 @llvm.hexagon.A2.tfr(i32) #0

attributes #0 = { nounwind readnone }
attributes #1 = { optsize }

0 comments on commit 025e2ea

Please sign in to comment.