38 #include "ProgramPartitioner.hh" 43 #include "tce_config.h" 44 #include <llvm/IR/Instruction.h> 55 #define ASSIGN_UNKNOWN_TO_EXTRAS 70 #if (!(defined(LLVM_3_5))) 71 #ifdef DEBUG_PROGRAM_PARTITIONER 72 std::cerr <<
"### ProgramPartitioner disabled for llvm 3.6+ " << std::endl;
77 #ifdef DEBUG_PROGRAM_PARTITIONER 78 std::cerr <<
"### Running ProgramPartitioner for " 79 << MF.getFunction()->getName().str() << std::endl;
88 #ifdef DEBUG_PROGRAM_PARTITIONER 96 llvm::MachineRegisterInfo& MRI = MF.getRegInfo();
98 hash_map<const llvm::MachineInstr*, unsigned> partitions;
101 for (MachineFunction::const_iterator i = MF.begin();
102 i != MF.end(); i++) {
103 bool changedT, changedD =
false;
110 for (MachineBasicBlock::const_iterator j = i->begin();
111 j != i->end(); j++) {
113 const llvm::MachineInstr& mi = *j;
115 if (partitions.find(&mi) != partitions.end())
119 changedT |= findNodeIndex(mi, partitions, MF, nodeIndex);
127 for (MachineBasicBlock::const_iterator j = i->end();
130 const llvm::MachineInstr& mi = *j;
132 if (partitions.find(&mi) != partitions.end())
134 unsigned nodeIndex = tmPlugin.extractElementLane(mi);
136 changedD |= findNodeIndex(mi, partitions, MF, nodeIndex);
140 }
while (changedT || changedD);
142 #ifdef ASSIGN_UNKNOWN_TO_EXTRAS 143 #ifdef DEBUG_PROGRAM_PARTITIONER 144 std::cerr <<
"[setting the rest to EX]" << std::endl;
150 for (MachineFunction::const_iterator i = MF.begin();
151 i != MF.end(); i++) {
153 for (MachineBasicBlock::const_iterator j = i->begin();
154 j != i->end(); j++) {
155 const llvm::MachineInstr& mi = *j;
157 #ifdef LLVM_OLDER_THAN_10 158 if (mi.getNumOperands() == 0 || !mi.getOperand(0).isReg() ||
159 !mi.getOperand(0).isDef() ||
160 llvm::TargetRegisterInfo::isPhysicalRegister(
161 mi.getOperand(0).getReg()))
163 if (mi.getNumOperands() == 0 || !mi.getOperand(0).isReg() ||
164 !mi.getOperand(0).isDef() ||
165 Register::isPhysicalRegister(
166 mi.getOperand(0).getReg()))
170 if (partitions.find(&mi) != partitions.end())
172 const llvm::MachineOperand& result = mi.getOperand(0);
173 const llvm::TargetRegisterClass* newRegClass =
174 tmPlugin.extrasRegClass(MRI.getRegClass(result.getReg()));
175 #ifdef DEBUG_PROGRAM_PARTITIONER 176 std::cerr <<
"[ORIGINAL REG CLASS " 177 << MRI.getRegClass(result.getReg())->getName()
180 MRI.setRegClass(result.getReg(), newRegClass);
181 #ifdef DEBUG_PROGRAM_PARTITIONER 182 std::cerr <<
"[ASSIGNED REG CLASS " 183 << newRegClass->getName() <<
"]" << std::endl;
207 const llvm::MachineInstr &mi,
208 hash_map<const llvm::MachineInstr*, unsigned>& partitions,
209 llvm::MachineFunction& MF,
210 unsigned int& nodeIndex) {
220 llvm::MachineRegisterInfo& MRI = MF.getRegInfo();
222 if (nodeIndex != UINT_MAX) {
223 #ifdef DEBUG_PROGRAM_PARTITIONER 224 std::cerr <<
"[EXTRACT lane " << nodeIndex <<
"] " << std::endl;
228 if (nodeIndex == UINT_MAX) {
234 for (
unsigned opr = 0; opr < mi.getNumOperands(); ++opr) {
235 const llvm::MachineOperand& operand = mi.getOperand(opr);
236 if (!operand.isReg())
continue;
238 llvm::MachineRegisterInfo::def_iterator di =
239 MRI.def_begin(operand.getReg());
240 if (di.atEnd())
continue;
242 const llvm::MachineInstr* parent = (*di).getParent();
245 if (parent == NULL)
continue;
246 if (partitions.find(parent) == partitions.end())
continue;
247 nodeIndex = partitions[parent];
251 if (nodeIndex == UINT_MAX &&
252 mi.memoperands_begin() != mi.memoperands_end()) {
255 for (llvm::MachineInstr::mmo_iterator mmoIter =
256 mi.memoperands_begin();
257 mmoIter != mi.memoperands_end(); ++mmoIter) {
259 llvm::MachineMemOperand* mo = *mmoIter;
261 if (mo->getValue() == NULL ||
262 !llvm::isa<const llvm::Instruction>(mo->getValue()))
265 const llvm::Instruction* instruction =
266 llvm::cast<const llvm::Instruction>(mo->getValue());
268 if (!instruction->getMetadata(
"wi")) {
271 MDNode *md = instruction->getMetadata(
"wi");
272 ConstantInt* id_x = NULL;
273 if (llvm::isa<MDNode>(md->getOperand(2))) {
278 MDNode *xyz = dyn_cast<MDNode>(md->getOperand(2));
285 #ifdef LLVM_OLDER_THAN_3_6 286 id_x = cast<llvm::ConstantInt>(xyz->getOperand(1));
288 id_x = cast<llvm::ConstantInt>(
289 dyn_cast<llvm::ConstantAsMetadata>(
290 xyz->getOperand(1))->getValue());
300 #ifdef LLVM_OLDER_THAN_3_6 301 id_x = cast<llvm::ConstantInt>(md->getOperand(2));
303 id_x = cast<llvm::ConstantInt>(
304 dyn_cast<llvm::ConstantAsMetadata>(
305 md->getOperand(2))->getValue());
311 (unsigned)id_x->getValue().getZExtValue() %
313 #ifdef DEBUG_PROGRAM_PARTITIONER 314 std::cerr <<
"[FOUND OCL WI METADATA: " <<
315 nodeIndex <<
"]" << std::endl;
319 #ifdef DEBUG_PROGRAM_PARTITIONER 320 if (nodeIndex != UINT_MAX) {
321 std::cerr <<
"[NODE INDEX " << nodeIndex <<
"]: ";
322 for (
int pad = 0; pad < nodeIndex; ++pad)
323 for (
int ws = 0; ws < 30; ++ws) std::cerr <<
" ";
325 std::cerr <<
"[NODE INDEX UNKNOWN]: ";
328 if (nodeIndex == UINT_MAX)
return false;
329 partitions[&mi] = nodeIndex;
333 for (
unsigned int i = 0; i < mi.getNumOperands(); i++) {
334 if (mi.getOperand(i).isReg() &&
335 mi.getOperand(i).isDef()) {
337 const llvm::MachineOperand& result = mi.getOperand(i);
338 #ifdef LLVM_OLDER_THAN_10 339 if (llvm::TargetRegisterInfo::isPhysicalRegister(
340 mi.getOperand(i).getReg()))
continue;
342 if (Register::isPhysicalRegister(
343 mi.getOperand(i).getReg()))
continue;
346 const llvm::TargetRegisterClass* nodeRegClass =
347 tmPlugin.
nodeRegClass(nodeIndex, MRI.getRegClass(result.getReg()));
348 #ifdef DEBUG_PROGRAM_PARTITIONER 349 std::cerr <<
"[ORIGINAL REG CLASS " 350 << MRI.getRegClass(result.getReg())->getName()
353 if (nodeRegClass == NULL) {
354 #ifdef DEBUG_PROGRAM_PARTITIONER 355 std::cerr <<
"[NO REG CLASS FOUND FOR THE NODE]" << std::endl;
358 #ifdef DEBUG_PROGRAM_PARTITIONER 359 std::cerr <<
"[ASSIGNED REG CLASS " 360 << nodeRegClass->getName() <<
"]" << std::endl;
362 MRI.setRegClass(result.getReg(), nodeRegClass);
virtual bool runOnMachineFunction(llvm::MachineFunction &MF) override
virtual bool doInitialization(llvm::Module &M) override
#define POP_COMPILER_DIAGS
int maxVectorSize() const
virtual unsigned int extractElementLane(const MachineInstr &mi) const =0
#define PRINT_VAR(VARIABLE__)
virtual bool doFinalization(llvm::Module &M) override
llvm::Pass * createProgramPartitionerPass()
virtual TCETargetMachinePlugin & targetPlugin() const
virtual bool findNodeIndex(const llvm::MachineInstr &I, hash_map< const llvm::MachineInstr *, unsigned > &partitions, llvm::MachineFunction &MF, unsigned int &index)
#define IGNORE_COMPILER_WARNING(X)
virtual const llvm::TargetRegisterClass * nodeRegClass(unsigned nodeId, const llvm::TargetRegisterClass *current) const =0