blob: a21d1728d81c13efaf7b6d25f9048d5f56beeb37 [file] [log] [blame]
Justin Holewinskic90e1492011-09-30 12:54:43 +00001//===-- PTXFPRoundingModePass.cpp - Assign rounding modes pass ------------===//
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 file defines a machine function pass that sets appropriate FP rounding
11// modes for all relevant instructions.
12//
13//===----------------------------------------------------------------------===//
14
15#define DEBUG_TYPE "ptx-fp-rounding-mode"
16
17#include "PTX.h"
18#include "PTXTargetMachine.h"
Justin Holewinski8c1dac52011-09-30 13:46:52 +000019#include "llvm/ADT/DenseMap.h"
Justin Holewinskic90e1492011-09-30 12:54:43 +000020#include "llvm/CodeGen/MachineFunctionPass.h"
21#include "llvm/CodeGen/MachineRegisterInfo.h"
22#include "llvm/Support/Debug.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/raw_ostream.h"
25
Benjamin Kramer0861f572011-11-26 23:01:57 +000026using namespace llvm;
27
Justin Holewinskic90e1492011-09-30 12:54:43 +000028// NOTE: PTXFPRoundingModePass should be executed just before emission.
29
Benjamin Kramer0861f572011-11-26 23:01:57 +000030namespace {
Justin Holewinskic90e1492011-09-30 12:54:43 +000031 /// PTXFPRoundingModePass - Pass to assign appropriate FP rounding modes to
32 /// all FP instructions. Essentially, this pass just looks for all FP
33 /// instructions that have a rounding mode set to RndDefault, and sets an
34 /// appropriate rounding mode based on the target device.
35 ///
36 class PTXFPRoundingModePass : public MachineFunctionPass {
37 private:
38 static char ID;
Justin Holewinski8c1dac52011-09-30 13:46:52 +000039
40 typedef std::pair<unsigned, unsigned> RndModeDesc;
41
Justin Holewinskic90e1492011-09-30 12:54:43 +000042 PTXTargetMachine& TargetMachine;
Justin Holewinski8c1dac52011-09-30 13:46:52 +000043 DenseMap<unsigned, RndModeDesc> Instrs;
Justin Holewinskic90e1492011-09-30 12:54:43 +000044
45 public:
46 PTXFPRoundingModePass(PTXTargetMachine &TM, CodeGenOpt::Level OptLevel)
47 : MachineFunctionPass(ID),
Justin Holewinski8c1dac52011-09-30 13:46:52 +000048 TargetMachine(TM) {
49 initializeMap();
50 }
Justin Holewinskic90e1492011-09-30 12:54:43 +000051
52 virtual bool runOnMachineFunction(MachineFunction &MF);
53
54 virtual const char *getPassName() const {
55 return "PTX FP Rounding Mode Pass";
56 }
57
58 private:
59
Justin Holewinski8c1dac52011-09-30 13:46:52 +000060 void initializeMap();
Justin Holewinskic90e1492011-09-30 12:54:43 +000061 void processInstruction(MachineInstr &MI);
62 }; // class PTXFPRoundingModePass
Benjamin Kramer0861f572011-11-26 23:01:57 +000063} // end anonymous namespace
Justin Holewinskic90e1492011-09-30 12:54:43 +000064
65using namespace llvm;
66
67char PTXFPRoundingModePass::ID = 0;
68
69bool PTXFPRoundingModePass::runOnMachineFunction(MachineFunction &MF) {
Justin Holewinskic90e1492011-09-30 12:54:43 +000070 // Look at each basic block
71 for (MachineFunction::iterator bbi = MF.begin(), bbe = MF.end(); bbi != bbe;
72 ++bbi) {
73 MachineBasicBlock &MBB = *bbi;
74 // Look at each instruction
75 for (MachineBasicBlock::iterator ii = MBB.begin(), ie = MBB.end();
76 ii != ie; ++ii) {
77 MachineInstr &MI = *ii;
78 processInstruction(MI);
79 }
80 }
81 return false;
82}
83
Justin Holewinski8c1dac52011-09-30 13:46:52 +000084void PTXFPRoundingModePass::initializeMap() {
85 using namespace PTXRoundingMode;
Justin Holewinskic90e1492011-09-30 12:54:43 +000086 const PTXSubtarget& ST = TargetMachine.getSubtarget<PTXSubtarget>();
Justin Holewinski8c1dac52011-09-30 13:46:52 +000087
88 // Build a map of default rounding mode for all instructions that need a
89 // rounding mode.
90 Instrs[PTX::FADDrr32] = std::make_pair(1U, (unsigned)RndNearestEven);
91 Instrs[PTX::FADDri32] = std::make_pair(1U, (unsigned)RndNearestEven);
92 Instrs[PTX::FADDrr64] = std::make_pair(1U, (unsigned)RndNearestEven);
93 Instrs[PTX::FADDri64] = std::make_pair(1U, (unsigned)RndNearestEven);
94 Instrs[PTX::FSUBrr32] = std::make_pair(1U, (unsigned)RndNearestEven);
95 Instrs[PTX::FSUBri32] = std::make_pair(1U, (unsigned)RndNearestEven);
96 Instrs[PTX::FSUBrr64] = std::make_pair(1U, (unsigned)RndNearestEven);
97 Instrs[PTX::FSUBri64] = std::make_pair(1U, (unsigned)RndNearestEven);
98 Instrs[PTX::FMULrr32] = std::make_pair(1U, (unsigned)RndNearestEven);
99 Instrs[PTX::FMULri32] = std::make_pair(1U, (unsigned)RndNearestEven);
100 Instrs[PTX::FMULrr64] = std::make_pair(1U, (unsigned)RndNearestEven);
101 Instrs[PTX::FMULri64] = std::make_pair(1U, (unsigned)RndNearestEven);
102
103 Instrs[PTX::FNEGrr32] = std::make_pair(1U, (unsigned)RndNone);
104 Instrs[PTX::FNEGri32] = std::make_pair(1U, (unsigned)RndNone);
105 Instrs[PTX::FNEGrr64] = std::make_pair(1U, (unsigned)RndNone);
106 Instrs[PTX::FNEGri64] = std::make_pair(1U, (unsigned)RndNone);
107
108 unsigned FDivRndMode = ST.fdivNeedsRoundingMode() ? RndNearestEven : RndNone;
109 Instrs[PTX::FDIVrr32] = std::make_pair(1U, FDivRndMode);
110 Instrs[PTX::FDIVri32] = std::make_pair(1U, FDivRndMode);
111 Instrs[PTX::FDIVrr64] = std::make_pair(1U, FDivRndMode);
112 Instrs[PTX::FDIVri64] = std::make_pair(1U, FDivRndMode);
113
114 unsigned FMADRndMode = ST.fmadNeedsRoundingMode() ? RndNearestEven : RndNone;
115 Instrs[PTX::FMADrrr32] = std::make_pair(1U, FMADRndMode);
116 Instrs[PTX::FMADrri32] = std::make_pair(1U, FMADRndMode);
117 Instrs[PTX::FMADrii32] = std::make_pair(1U, FMADRndMode);
118 Instrs[PTX::FMADrrr64] = std::make_pair(1U, FMADRndMode);
119 Instrs[PTX::FMADrri64] = std::make_pair(1U, FMADRndMode);
120 Instrs[PTX::FMADrii64] = std::make_pair(1U, FMADRndMode);
121
122 Instrs[PTX::FSQRTrr32] = std::make_pair(1U, (unsigned)RndNearestEven);
123 Instrs[PTX::FSQRTri32] = std::make_pair(1U, (unsigned)RndNearestEven);
124 Instrs[PTX::FSQRTrr64] = std::make_pair(1U, (unsigned)RndNearestEven);
125 Instrs[PTX::FSQRTri64] = std::make_pair(1U, (unsigned)RndNearestEven);
126
127 Instrs[PTX::FSINrr32] = std::make_pair(1U, (unsigned)RndApprox);
128 Instrs[PTX::FSINri32] = std::make_pair(1U, (unsigned)RndApprox);
129 Instrs[PTX::FSINrr64] = std::make_pair(1U, (unsigned)RndApprox);
130 Instrs[PTX::FSINri64] = std::make_pair(1U, (unsigned)RndApprox);
131 Instrs[PTX::FCOSrr32] = std::make_pair(1U, (unsigned)RndApprox);
132 Instrs[PTX::FCOSri32] = std::make_pair(1U, (unsigned)RndApprox);
133 Instrs[PTX::FCOSrr64] = std::make_pair(1U, (unsigned)RndApprox);
134 Instrs[PTX::FCOSri64] = std::make_pair(1U, (unsigned)RndApprox);
135
136 Instrs[PTX::CVTu16f32] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
137 Instrs[PTX::CVTs16f32] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
138 Instrs[PTX::CVTu16f64] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
139 Instrs[PTX::CVTs16f64] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
140 Instrs[PTX::CVTu32f32] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
141 Instrs[PTX::CVTs32f32] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
142 Instrs[PTX::CVTu32f64] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
143 Instrs[PTX::CVTs32f64] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
144 Instrs[PTX::CVTu64f32] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
145 Instrs[PTX::CVTs64f32] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
146 Instrs[PTX::CVTu64f64] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
147 Instrs[PTX::CVTs64f64] = std::make_pair(1U, (unsigned)RndTowardsZeroInt);
148
149 Instrs[PTX::CVTf32u16] = std::make_pair(1U, (unsigned)RndNearestEven);
150 Instrs[PTX::CVTf32s16] = std::make_pair(1U, (unsigned)RndNearestEven);
151 Instrs[PTX::CVTf32u32] = std::make_pair(1U, (unsigned)RndNearestEven);
152 Instrs[PTX::CVTf32s32] = std::make_pair(1U, (unsigned)RndNearestEven);
153 Instrs[PTX::CVTf32u64] = std::make_pair(1U, (unsigned)RndNearestEven);
154 Instrs[PTX::CVTf32s64] = std::make_pair(1U, (unsigned)RndNearestEven);
155 Instrs[PTX::CVTf32f64] = std::make_pair(1U, (unsigned)RndNearestEven);
156 Instrs[PTX::CVTf64u16] = std::make_pair(1U, (unsigned)RndNearestEven);
157 Instrs[PTX::CVTf64s16] = std::make_pair(1U, (unsigned)RndNearestEven);
158 Instrs[PTX::CVTf64u32] = std::make_pair(1U, (unsigned)RndNearestEven);
159 Instrs[PTX::CVTf64s32] = std::make_pair(1U, (unsigned)RndNearestEven);
160 Instrs[PTX::CVTf64u64] = std::make_pair(1U, (unsigned)RndNearestEven);
161 Instrs[PTX::CVTf64s64] = std::make_pair(1U, (unsigned)RndNearestEven);
162}
163
164void PTXFPRoundingModePass::processInstruction(MachineInstr &MI) {
165 // Is this an instruction that needs a rounding mode?
166 if (Instrs.count(MI.getOpcode())) {
167 const RndModeDesc &Desc = Instrs[MI.getOpcode()];
168 // Get the rounding mode operand
169 MachineOperand &Op = MI.getOperand(Desc.first);
170 // Update the rounding mode if needed
171 if (Op.getImm() == PTXRoundingMode::RndDefault) {
172 Op.setImm(Desc.second);
Justin Holewinskic90e1492011-09-30 12:54:43 +0000173 }
Justin Holewinskic90e1492011-09-30 12:54:43 +0000174 }
175}
176
177FunctionPass *llvm::createPTXFPRoundingModePass(PTXTargetMachine &TM,
178 CodeGenOpt::Level OptLevel) {
179 return new PTXFPRoundingModePass(TM, OptLevel);
180}
181