Skip to content

Commit fed67f7

Browse files
quic-asaravanHarsha Jagasiakparzysz
committed
[HEXAGON] Utilize new mask instruction
Co-authored-by: Harsha Jagasia <[email protected]> Co-authored-by: Krzysztof Parzyszek <[email protected]>
1 parent a8e1c3e commit fed67f7

File tree

4 files changed

+138
-0
lines changed

4 files changed

+138
-0
lines changed

llvm/lib/Target/Hexagon/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ add_llvm_target(HexagonCodeGen
4848
HexagonLoopIdiomRecognition.cpp
4949
HexagonMachineFunctionInfo.cpp
5050
HexagonMachineScheduler.cpp
51+
HexagonMask.cpp
5152
HexagonMCInstLower.cpp
5253
HexagonNewValueJump.cpp
5354
HexagonOptAddrMode.cpp
+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
//===-- HexagonMask.cpp - replace const ext tfri with mask ------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
//===----------------------------------------------------------------------===//
10+
11+
#define DEBUG_TYPE "mask"
12+
13+
#include "HexagonMachineFunctionInfo.h"
14+
#include "HexagonSubtarget.h"
15+
#include "HexagonTargetMachine.h"
16+
#include "llvm/ADT/SmallString.h"
17+
#include "llvm/ADT/Statistic.h"
18+
#include "llvm/ADT/Twine.h"
19+
#include "llvm/CodeGen/MachineFunction.h"
20+
#include "llvm/CodeGen/MachineFunctionPass.h"
21+
#include "llvm/CodeGen/MachineInstrBuilder.h"
22+
#include "llvm/CodeGen/Passes.h"
23+
#include "llvm/CodeGen/TargetInstrInfo.h"
24+
#include "llvm/IR/Function.h"
25+
#include "llvm/IR/Module.h"
26+
#include "llvm/Support/CommandLine.h"
27+
#include "llvm/Support/Debug.h"
28+
#include "llvm/Support/MathExtras.h"
29+
#include "llvm/Target/TargetMachine.h"
30+
31+
using namespace llvm;
32+
33+
namespace llvm {
34+
FunctionPass *createHexagonMask();
35+
void initializeHexagonMaskPass(PassRegistry &);
36+
37+
class HexagonMask : public MachineFunctionPass {
38+
public:
39+
static char ID;
40+
HexagonMask() : MachineFunctionPass(ID) {
41+
PassRegistry &Registry = *PassRegistry::getPassRegistry();
42+
initializeHexagonMaskPass(Registry);
43+
}
44+
45+
StringRef getPassName() const override {
46+
return "Hexagon replace const ext tfri with mask";
47+
}
48+
bool runOnMachineFunction(MachineFunction &MF) override;
49+
50+
private:
51+
const HexagonInstrInfo *HII;
52+
void replaceConstExtTransferImmWithMask(MachineFunction &MF);
53+
};
54+
55+
char HexagonMask::ID = 0;
56+
57+
void HexagonMask::replaceConstExtTransferImmWithMask(MachineFunction &MF) {
58+
for (auto &MBB : MF) {
59+
for (auto &MI : llvm::make_early_inc_range(MBB)) {
60+
if (MI.getOpcode() != Hexagon::A2_tfrsi)
61+
continue;
62+
63+
const MachineOperand &Op0 = MI.getOperand(0);
64+
const MachineOperand &Op1 = MI.getOperand(1);
65+
if (!Op1.isImm())
66+
continue;
67+
int32_t V = Op1.getImm();
68+
if (isInt<16>(V))
69+
continue;
70+
71+
unsigned Idx, Len;
72+
if (!isShiftedMask_32(V, Idx, Len))
73+
continue;
74+
if (!isUInt<5>(Idx) || !isUInt<5>(Len))
75+
continue;
76+
77+
BuildMI(MBB, MI, MI.getDebugLoc(), HII->get(Hexagon::S2_mask),
78+
Op0.getReg())
79+
.addImm(Len)
80+
.addImm(Idx);
81+
MBB.erase(MI);
82+
}
83+
}
84+
}
85+
86+
bool HexagonMask::runOnMachineFunction(MachineFunction &MF) {
87+
auto &HST = MF.getSubtarget<HexagonSubtarget>();
88+
HII = HST.getInstrInfo();
89+
const Function &F = MF.getFunction();
90+
91+
if (!F.hasFnAttribute(Attribute::OptimizeForSize))
92+
return false;
93+
// The mask instruction available in v66 can be used to generate values in registers using 2 immediates
94+
// Eg. to form 0x07fffffc in R0, you would write "R0 = mask(#25,#2)"
95+
// Since it is a single-word instruction, it takes less code size than a constant-extended transfer at Os
96+
replaceConstExtTransferImmWithMask(MF);
97+
98+
return true;
99+
}
100+
101+
} // namespace llvm
102+
103+
//===----------------------------------------------------------------------===//
104+
// Public Constructor Functions
105+
//===----------------------------------------------------------------------===//
106+
107+
INITIALIZE_PASS(HexagonMask, "hexagon-mask", "Hexagon mask", false, false)
108+
109+
FunctionPass *llvm::createHexagonMask() { return new HexagonMask(); }

llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ static cl::opt<bool>
5959
DisableHCP("disable-hcp", cl::Hidden,
6060
cl::desc("Disable Hexagon constant propagation"));
6161

62+
static cl::opt<bool> DisableHexagonMask(
63+
"disable-mask", cl::Hidden,
64+
cl::desc("Disable Hexagon specific Mask generation pass"));
65+
6266
static cl::opt<bool> DisableStoreWidening("disable-store-widen", cl::Hidden,
6367
cl::init(false),
6468
cl::desc("Disable store widening"));
@@ -180,6 +184,8 @@ void initializeHexagonGenMuxPass(PassRegistry &);
180184
void initializeHexagonHardwareLoopsPass(PassRegistry &);
181185
void initializeHexagonLoopIdiomRecognizeLegacyPassPass(PassRegistry &);
182186
void initializeHexagonLoopAlignPass(PassRegistry &);
187+
void initializeHexagonMaskPass(PassRegistry &);
188+
void initializeHexagonMergeActivateWeightPass(PassRegistry &);
183189
void initializeHexagonNewValueJumpPass(PassRegistry &);
184190
void initializeHexagonOptAddrModePass(PassRegistry &);
185191
void initializeHexagonPacketizerPass(PassRegistry &);
@@ -213,6 +219,8 @@ FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM,
213219
CodeGenOptLevel OptLevel);
214220
FunctionPass *createHexagonLoopAlign();
215221
FunctionPass *createHexagonLoopRescheduling();
222+
FunctionPass *createHexagonMask();
223+
FunctionPass *createHexagonMergeActivateWeight();
216224
FunctionPass *createHexagonNewValueJump();
217225
FunctionPass *createHexagonOptAddrMode();
218226
FunctionPass *createHexagonOptimizeSZextends();
@@ -474,10 +482,13 @@ void HexagonPassConfig::addPostRegAlloc() {
474482
}
475483

476484
void HexagonPassConfig::addPreSched2() {
485+
bool NoOpt = (getOptLevel() == CodeGenOptLevel::None);
477486
addPass(createHexagonCopyToCombine());
478487
if (getOptLevel() != CodeGenOptLevel::None)
479488
addPass(&IfConverterID);
480489
addPass(createHexagonSplitConst32AndConst64());
490+
if (!NoOpt && !DisableHexagonMask)
491+
addPass(createHexagonMask());
481492
}
482493

483494
void HexagonPassConfig::addPreEmitPass() {

llvm/test/CodeGen/Hexagon/mask.ll

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
; RUN: llc -mtriple=hexagon -mcpu=hexagonv73 < %s | FileCheck %s
2+
3+
target triple = "hexagon"
4+
5+
; CHECK-LABEL: test1:
6+
; CHECK: r0 = mask(#25,#2)
7+
; Function Attrs: optsize
8+
define i32 @test1() #1 {
9+
entry:
10+
%0 = call i32 @llvm.hexagon.A2.tfr(i32 134217724)
11+
ret i32 %0
12+
}
13+
14+
declare i32 @llvm.hexagon.A2.tfr(i32) #0
15+
16+
attributes #0 = { nounwind readnone }
17+
attributes #1 = { optsize }

0 commit comments

Comments
 (0)