Skip to content

Commit 8123b96

Browse files
author
Ron Lieberman
committedAug 1, 2016
[Hexagon] Generate vector printing instructions
llvm-svn: 277370
1 parent 38115ff commit 8123b96

File tree

4 files changed

+219
-0
lines changed

4 files changed

+219
-0
lines changed
 

‎llvm/lib/Target/Hexagon/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ add_llvm_target(HexagonCodeGen
5454
HexagonTargetMachine.cpp
5555
HexagonTargetObjectFile.cpp
5656
HexagonTargetTransformInfo.cpp
57+
HexagonVectorPrint.cpp
5758
HexagonVLIWPacketizer.cpp
5859
RDFCopy.cpp
5960
RDFDeadCode.cpp

‎llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ static cl::opt<bool> EnableLoopResched("hexagon-loop-resched", cl::init(true),
8686
static cl::opt<bool> HexagonNoOpt("hexagon-noopt", cl::init(false),
8787
cl::Hidden, cl::desc("Disable backend optimizations"));
8888

89+
static cl::opt<bool> EnableVectorPrint("enable-hexagon-vector-print",
90+
cl::Hidden, cl::ZeroOrMore, cl::init(false),
91+
cl::desc("Enable Hexagon Vector print instr pass"));
92+
8993
/// HexagonTargetMachineModule - Note that this is used on hosts that
9094
/// cannot link in a library unless there are references into the
9195
/// library. In particular, it seems that it is not possible to get
@@ -135,6 +139,7 @@ namespace llvm {
135139
FunctionPass *createHexagonSplitConst32AndConst64();
136140
FunctionPass *createHexagonSplitDoubleRegs();
137141
FunctionPass *createHexagonStoreWidening();
142+
FunctionPass *createHexagonVectorPrint();
138143
} // end namespace llvm;
139144

140145
static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) {
@@ -331,6 +336,8 @@ void HexagonPassConfig::addPreEmitPass() {
331336

332337
addPass(createHexagonPacketizer(), false);
333338
}
339+
if (EnableVectorPrint)
340+
addPass(createHexagonVectorPrint(), false);
334341

335342
// Add CFI instructions if necessary.
336343
addPass(createHexagonCallFrameInformation(), false);
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
//===-- HexagonVectorPrint.cpp - Generate vector printing instructions -===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This pass adds the capability to generate pseudo vector/predicate register
11+
// printing instructions. These pseudo instructions should be used with the
12+
// simulator, NEVER on hardware.
13+
//
14+
//===----------------------------------------------------------------------===//
15+
16+
#define DEBUG_TYPE "hexagon-vector-print"
17+
18+
#include "HexagonTargetMachine.h"
19+
#include "llvm/CodeGen/MachineInstrBuilder.h"
20+
21+
using namespace llvm;
22+
23+
namespace llvm {
24+
FunctionPass *createHexagonVectorPrint();
25+
void initializeHexagonVectorPrintPass(PassRegistry&);
26+
}
27+
28+
29+
namespace {
30+
31+
class HexagonVectorPrint : public MachineFunctionPass {
32+
const HexagonSubtarget *QST;
33+
const HexagonInstrInfo *QII;
34+
const HexagonRegisterInfo *QRI;
35+
36+
public:
37+
static char ID;
38+
HexagonVectorPrint() : MachineFunctionPass(ID),
39+
QST(0), QII(0), QRI(0) {
40+
initializeHexagonVectorPrintPass(*PassRegistry::getPassRegistry());
41+
}
42+
43+
const char *getPassName() const override {
44+
return "Hexagon VectorPrint pass";
45+
}
46+
bool runOnMachineFunction(MachineFunction &Fn) override;
47+
};
48+
49+
char HexagonVectorPrint::ID = 0;
50+
51+
static bool isVecReg(unsigned Reg) {
52+
return (Reg >= Hexagon::V0 && Reg <= Hexagon::V31)
53+
|| (Reg >= Hexagon::W0 && Reg <= Hexagon::W15)
54+
|| (Reg >= Hexagon::Q0 && Reg <= Hexagon::Q3);
55+
}
56+
57+
std::string getStringReg(unsigned R) {
58+
if (R >= Hexagon::V0 && R <= Hexagon::V31) {
59+
static const char* S[] = { "20", "21", "22", "23", "24", "25", "26", "27",
60+
"28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
61+
"30", "31", "32", "33", "34", "35", "36", "37",
62+
"38", "39", "3a", "3b", "3c", "3d", "3e", "3f"};
63+
return S[R-Hexagon::V0];
64+
}
65+
if (R >= Hexagon::Q0 && R <= Hexagon::Q3) {
66+
static const char* S[] = { "00", "01", "02", "03"};
67+
return S[R-Hexagon::Q0];
68+
69+
}
70+
llvm_unreachable("valid vreg");
71+
}
72+
73+
static void addAsmInstr(MachineBasicBlock *MBB, unsigned Reg,
74+
MachineBasicBlock::instr_iterator I,
75+
const DebugLoc &DL, const HexagonInstrInfo *QII,
76+
MachineFunction &Fn) {
77+
78+
std::string VDescStr = ".long 0x1dffe0" + getStringReg(Reg);
79+
const char *cstr = Fn.createExternalSymbolName(VDescStr.c_str());
80+
unsigned ExtraInfo = InlineAsm::Extra_HasSideEffects;
81+
BuildMI(*MBB, I, DL, QII->get(TargetOpcode::INLINEASM))
82+
.addExternalSymbol(cstr)
83+
.addImm(ExtraInfo);
84+
}
85+
86+
static bool getInstrVecReg(const MachineInstr &MI, unsigned &Reg) {
87+
if (MI.getNumOperands() < 1) return false;
88+
// Vec load or compute.
89+
if (MI.getOperand(0).isReg() && MI.getOperand(0).isDef()) {
90+
Reg = MI.getOperand(0).getReg();
91+
if (isVecReg(Reg))
92+
return true;
93+
}
94+
// Vec store.
95+
if (MI.mayStore() && MI.getNumOperands() >= 3 && MI.getOperand(2).isReg()) {
96+
Reg = MI.getOperand(2).getReg();
97+
if (isVecReg(Reg))
98+
return true;
99+
}
100+
// Vec store post increment.
101+
if (MI.mayStore() && MI.getNumOperands() >= 4 && MI.getOperand(3).isReg()) {
102+
Reg = MI.getOperand(3).getReg();
103+
if (isVecReg(Reg))
104+
return true;
105+
}
106+
return false;
107+
}
108+
109+
bool HexagonVectorPrint::runOnMachineFunction(MachineFunction &Fn) {
110+
bool Changed = false;
111+
QST = &Fn.getSubtarget<HexagonSubtarget>();
112+
QRI = QST->getRegisterInfo();
113+
QII = QST->getInstrInfo();
114+
std::vector<MachineInstr *> VecPrintList;
115+
for (auto &MBB : Fn)
116+
for (auto &MI : MBB) {
117+
if (MI.isBundle()) {
118+
MachineBasicBlock::instr_iterator MII = MI.getIterator();
119+
for (++MII; MII != MBB.instr_end() && MII->isInsideBundle(); ++MII) {
120+
if (MII->getNumOperands() < 1) continue;
121+
unsigned Reg = 0;
122+
if (getInstrVecReg(*MII, Reg)) {
123+
VecPrintList.push_back((&*MII));
124+
DEBUG(dbgs() << "Found vector reg inside bundle \n"; MII->dump());
125+
}
126+
}
127+
} else {
128+
unsigned Reg = 0;
129+
if (getInstrVecReg(MI, Reg)) {
130+
VecPrintList.push_back(&MI);
131+
DEBUG(dbgs() << "Found vector reg \n"; MI.dump());
132+
}
133+
}
134+
}
135+
136+
Changed = VecPrintList.size() > 0;
137+
if (!Changed) return Changed;
138+
139+
for (auto *I : VecPrintList) {
140+
DebugLoc DL = I->getDebugLoc();
141+
MachineBasicBlock *MBB = I->getParent();
142+
DEBUG(dbgs() << "Evaluating V MI\n"; I->dump());
143+
unsigned Reg = 0;
144+
assert(getInstrVecReg(*I, Reg) && "Need a vector reg");
145+
MachineBasicBlock::instr_iterator MII = I->getIterator();
146+
if (I->isInsideBundle()) {
147+
DEBUG(dbgs() << "add to end of bundle\n"; I->dump());
148+
while (MII->isInsideBundle()) ++MII;
149+
} else {
150+
DEBUG(dbgs() << "add after instruction\n"; I->dump());
151+
MII++;
152+
}
153+
if (Reg >= Hexagon::V0 && Reg <= Hexagon::V31) {
154+
DEBUG(dbgs() << "adding dump for V" << Reg-Hexagon::V0 << '\n');
155+
addAsmInstr(MBB, Reg, MII, DL, QII, Fn);
156+
} else if (Reg >= Hexagon::W0 && Reg <= Hexagon::W15) {
157+
DEBUG(dbgs() << "adding dump for W" << Reg-Hexagon::W0 << '\n');
158+
addAsmInstr(MBB, Hexagon::V0 + (Reg - Hexagon::W0) * 2 + 1,
159+
MII, DL, QII, Fn);
160+
addAsmInstr(MBB, Hexagon::V0 + (Reg - Hexagon::W0) * 2,
161+
MII, DL, QII, Fn);
162+
} else if (Reg >= Hexagon::Q0 && Reg <= Hexagon::Q3) {
163+
DEBUG(dbgs() << "adding dump for Q" << Reg-Hexagon::Q0 << '\n');
164+
addAsmInstr(MBB, Reg, MII, DL, QII, Fn);
165+
} else
166+
llvm_unreachable("Bad Vector reg");
167+
}
168+
return Changed;
169+
}
170+
171+
}
172+
//===----------------------------------------------------------------------===//
173+
// Public Constructor Functions
174+
//===----------------------------------------------------------------------===//
175+
INITIALIZE_PASS(HexagonVectorPrint, "hexagon-vector-print",
176+
"Hexagon VectorPrint pass", false, false)
177+
178+
FunctionPass *llvm::createHexagonVectorPrint() {
179+
return new HexagonVectorPrint();
180+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
; RUN: llc -march=hexagon -mcpu=hexagonv60 -enable-hexagon-hvx -disable-hexagon-shuffle=0 -O2 -enable-hexagon-vector-print < %s | FileCheck --check-prefix=CHECK %s
2+
; generate .long XXXX which is a vector debug print instruction.
3+
; CHECK: .long 0x1dffe0
4+
target datalayout = "e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:32:32-f64:64:64-f32:32:32-v64:64:64-v32:32:32-a:0-n16:32"
5+
target triple = "hexagon"
6+
7+
; Function Attrs: nounwind
8+
define void @do_vecs(i8* nocapture readonly %a, i8* nocapture readonly %b, i8* nocapture %c) #0 {
9+
entry:
10+
%0 = bitcast i8* %a to <16 x i32>*
11+
%1 = load <16 x i32>, <16 x i32>* %0, align 4, !tbaa !1
12+
%2 = bitcast i8* %b to <16 x i32>*
13+
%3 = load <16 x i32>, <16 x i32>* %2, align 4, !tbaa !1
14+
%4 = tail call <16 x i32> @llvm.hexagon.V6.vaddw(<16 x i32> %1, <16 x i32> %3)
15+
%5 = bitcast i8* %c to <16 x i32>*
16+
store <16 x i32> %4, <16 x i32>* %5, align 4, !tbaa !1
17+
ret void
18+
}
19+
20+
; Function Attrs: nounwind readnone
21+
declare <16 x i32> @llvm.hexagon.V6.vaddw(<16 x i32>, <16 x i32>) #1
22+
23+
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
24+
attributes #1 = { nounwind readnone }
25+
26+
!llvm.ident = !{!0}
27+
28+
!0 = !{!"QuIC LLVM Hexagon Clang version 7.x-pre-unknown"}
29+
!1 = !{!2, !2, i64 0}
30+
!2 = !{!"omnipotent char", !3, i64 0}
31+
!3 = !{!"Simple C/C++ TBAA"}

0 commit comments

Comments
 (0)
Please sign in to comment.