OpenASIP  2.0
LLVMTCERISCVIntrinsicsLowering.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2022 Tampere University.
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 /**
19  * @file LLVMTCERISCVIntrinsicsLowering.cc
20  *
21  * Pass for lowering RISC-V intrinsics
22  *
23  * @author Kari Hepola 2022
24  * @note rating: red
25  */
26 
27 #include "CompilerWarnings.hh"
28 
29 IGNORE_COMPILER_WARNING("-Wunused-parameter")
30 
31 #include <llvm/CodeGen/MachineFunction.h>
32 #include "tce_config.h"
33 #include <llvm/IR/Function.h>
34 #include <llvm/Support/CommandLine.h>
35 #include <llvm/Analysis/AliasAnalysis.h>
36 
37 #include <iostream>
38 
40 #include "Application.hh"
41 #include "InterPassData.hh"
42 #include "LLVMTCECmdLineOptions.hh"
43 #include "OperationPool.hh"
44 #include "BEMGenerator.hh"
45 #include "Exception.hh"
46 
48 
49 namespace llvm {
50 
52 
54  : MachineFunctionPass(ID) {
55  auto* option = static_cast<llvm::cl::opt<std::string>*>(
56  llvm::cl::getRegisteredOptions().lookup("adf"));
57  const std::string adf = option->getValue();
58  try {
60  } catch (const Exception& e) {
62  << "TCE: unable to load the ADF:" << std::endl
63  << e.errorMessage() << std::endl
64  << "Make sure you give the"
65  << " correct adf with the -adf switch to llc";
66  }
67  bem_ = BEMGenerator(*mach_).generate();
69 }
70 
71 bool
73  return false;
74 }
75 
78  InstructionFormat* format = NULL;
79  for (int f = 0; f < bem_->instructionFormatCount(); f++) {
80  if (bem_->instructionFormat(f).name() == "riscv_r_type") {
81  format = &bem_->instructionFormat(f);
82  break;
83  }
84  }
85  if (format == NULL) {
86  std::string msg = "BEM does not identify R format ";
87  throw InvalidData(__FILE__, __LINE__, __func__, msg);
88  }
89  return format;
90 }
91 
92 std::string
93 LLVMTCERISCVIntrinsicsLowering::findRegs(const std::string& s) const {
94  std::vector<TCEString> asmSubStrings = StringTools::chopString(s, " ");
95  std::string regs = "";
96  int foundRegs = 0;
97  for (TCEString i : asmSubStrings) {
98  std::string ss = static_cast<std::string>(i);
99  if (StringTools::containsChar(ss, '$')) {
100  regs += " " + ss;
101  foundRegs++;
102  }
103  }
104  if (foundRegs != 3) {
105  std::string msg =
106  "Invalid amount of register operands, 3 required, found " +
107  std::to_string(foundRegs);
108  throw InvalidData(__FILE__, __LINE__, __func__, msg);
109  }
110  return regs;
111 }
112 
113 std::string
115  const std::string& s) const {
116  std::vector<TCEString> asmSubStrings = StringTools::chopString(s, " ");
117  std::string opName = "";
118  for (TCEString i : asmSubStrings) {
119  std::string ss = static_cast<std::string>(i);
120  if (StringTools::containsChar(ss, '/')) {
121  ss = StringTools::replaceAllOccurrences(ss, "//", "");
123  if (rFormat_->hasOperation(ss)) {
124  opName = ss;
125  } else {
126  std::string msg = "Machine does not have operation: " + ss;
127  throw InvalidData(__FILE__, __LINE__, __func__, msg);
128  }
129  }
130  }
131  if (opName == "") {
132  const std::string msg =
133  "Warning: Failed to find operation name from: \"" + s + "\"";
134  std::cerr << msg << std::endl;
135  //std::string msg = "Failed to find operation name from: " + s;
136  //throw InvalidData(__FILE__, __LINE__, __func__, msg);
137  }
138  return opName;
139 }
140 
141 std::vector<int>
143  const MachineBasicBlock::iterator& it) const {
144  const unsigned OpIdx = 0;
145  std::vector<int> regIdxs;
146  const std::string asmString =
147  std::string(it->getOperand(OpIdx).getSymbolName());
148  for (unsigned o = 0; o < it->getNumOperands(); o++) {
149  const MachineOperand& mo = it->getOperand(o);
150  if (mo.isReg()) {
151  int idx = mo.getReg() - 40;
152  regIdxs.push_back(idx);
153  if (idx < 0 && idx > 31) {
154  std::string msg =
155  "Invalid register index: " + std::to_string(idx) +
156  " in instruction: " + asmString;
157  throw InvalidData(__FILE__, __LINE__, __func__, msg);
158  };
159  }
160  }
161  if (regIdxs.size() != 3) {
162  std::string msg = "3 reg operands required, found " +
163  std::to_string(regIdxs.size()) +
164  " in instruction: " + asmString;
165  throw InvalidData(__FILE__, __LINE__, __func__, msg);
166  }
167  return regIdxs;
168 }
169 
170 int
172  const std::string& opName, const std::vector<int>& regIdxs) const {
173  const int fu3Mask = 0b1110000000;
174  const int fu7Mask = 0b11111110000000000;
175  const int opcodeMask = 0b1111111;
176  int encoding = rFormat_->encoding(opName);
177  const int fu3Enc = ((encoding & fu3Mask) >> 7);
178  const int fu7Enc = ((encoding & fu7Mask) >> 10);
179  const int opcodeEnc = encoding & opcodeMask;
180  const int shiftedEnc = (fu7Enc << 25) + (fu3Enc << 12) + opcodeEnc;
181 
182  encoding = shiftedEnc + (regIdxs.at(0) << 7) + (regIdxs.at(1) << 15) +
183  (regIdxs.at(2) << 20);
184 
185  return encoding;
186 }
187 
188 bool
190  for (MachineFunction::iterator i = MF.begin(); i != MF.end(); i++) {
191  for (MachineBasicBlock::iterator j = i->begin(); j != i->end(); j++) {
192  if (j->isInlineAsm()) {
193  const unsigned OpIdx = 0;
194  std::string asmString =
195  std::string(j->getOperand(OpIdx).getSymbolName());
196  const std::string opName = findOperationName(asmString);
197  if (opName == "") {
198  continue;
199  }
200  const std::string regs = findRegs(asmString);
201  const std::vector<int> regIdxs = findRegIndexes(j);
202 
203  int encoding = constructEncoding(opName, regIdxs);
204  std::string* cName = new std::string(
205  ".long " + std::to_string(encoding) + "; #" + opName +
206  regs);
207  j->getOperand(OpIdx).ChangeToES(
208  cName->c_str(), j->getOperand(OpIdx).getTargetFlags());
209  }
210  }
211  }
212  return false;
213 }
214 
215 FunctionPass*
216 createRISCVIntrinsicsPass(const char* /*target*/) {
217  return new LLVMTCERISCVIntrinsicsLowering();
218 }
219 
220 } // namespace llvm
BinaryEncoding::instructionFormat
InstructionFormat & instructionFormat(int index) const
Definition: BinaryEncoding.cc:521
llvm::LLVMTCERISCVIntrinsicsLowering::constructEncoding
int constructEncoding(const std::string &opName, const std::vector< int > &regIdxs) const
Definition: LLVMTCERISCVIntrinsicsLowering.cc:171
InstructionFormat::name
std::string name() const
Definition: InstructionFormat.cc:115
llvm
Definition: InlineAsmParser.hh:49
StringTools::containsChar
static bool containsChar(const std::string &source, char ch, bool caseSensitive=true)
Definition: StringTools.cc:101
BEMGenerator.hh
llvm::LLVMTCERISCVIntrinsicsLowering::rFormat_
InstructionFormat * rFormat_
Definition: LLVMTCERISCVIntrinsicsLowering.hh:62
Exception.hh
llvm::LLVMTCERISCVIntrinsicsLowering::findRegIndexes
std::vector< int > findRegIndexes(const MachineBasicBlock::iterator &it) const
Definition: LLVMTCERISCVIntrinsicsLowering.cc:142
llvm::LLVMTCERISCVIntrinsicsLowering::findRFormat
InstructionFormat * findRFormat()
Definition: LLVMTCERISCVIntrinsicsLowering.cc:77
llvm::LLVMTCERISCVIntrinsicsLowering::mach_
TTAMachine::Machine * mach_
Definition: LLVMTCERISCVIntrinsicsLowering.hh:60
Application::logStream
static std::ostream & logStream()
Definition: Application.cc:155
StringTools::replaceAllOccurrences
static std::string replaceAllOccurrences(const std::string &source, const std::string &occurrence, const std::string &newString)
Definition: StringTools.cc:295
llvm::LLVMTCERISCVIntrinsicsLowering::doInitialization
virtual bool doInitialization(Module &m)
Definition: LLVMTCERISCVIntrinsicsLowering.cc:72
BEMGenerator
Definition: BEMGenerator.hh:61
llvm::LLVMTCERISCVIntrinsicsLowering::LLVMTCERISCVIntrinsicsLowering
LLVMTCERISCVIntrinsicsLowering()
Definition: LLVMTCERISCVIntrinsicsLowering.cc:53
llvm::LLVMTCERISCVIntrinsicsLowering
Definition: LLVMTCERISCVIntrinsicsLowering.hh:42
InvalidData
Definition: Exception.hh:149
llvm::LLVMTCERISCVIntrinsicsLowering::findRegs
std::string findRegs(const std::string &s) const
Definition: LLVMTCERISCVIntrinsicsLowering.cc:93
LLVMTCECmdLineOptions.hh
llvm::createRISCVIntrinsicsPass
FunctionPass * createRISCVIntrinsicsPass(const char *)
Definition: LLVMTCERISCVIntrinsicsLowering.cc:216
Application.hh
__func__
#define __func__
Definition: Application.hh:67
llvm::LLVMTCERISCVIntrinsicsLowering::runOnMachineFunction
virtual bool runOnMachineFunction(MachineFunction &MF)
Definition: LLVMTCERISCVIntrinsicsLowering.cc:189
Exception
Definition: Exception.hh:54
llvm::LLVMTCERISCVIntrinsicsLowering::bem_
BinaryEncoding * bem_
Definition: LLVMTCERISCVIntrinsicsLowering.hh:61
InstructionFormat::hasOperation
bool hasOperation(const std::string &op) const
Definition: InstructionFormat.cc:104
InstructionFormat
Definition: InstructionFormat.hh:46
BinaryEncoding::instructionFormatCount
int instructionFormatCount() const
Definition: BinaryEncoding.cc:488
Exception::errorMessage
std::string errorMessage() const
Definition: Exception.cc:123
IGNORE_COMPILER_WARNING
#define IGNORE_COMPILER_WARNING(X)
Definition: CompilerWarnings.hh:51
InterPassData.hh
TCEString
Definition: TCEString.hh:53
StringTools::chopString
static std::vector< TCEString > chopString(const std::string &source, const std::string &delimiters)
Definition: StringTools.cc:181
POP_COMPILER_DIAGS
#define POP_COMPILER_DIAGS
Definition: CompilerWarnings.hh:68
llvm::LLVMTCERISCVIntrinsicsLowering::ID
static char ID
Definition: LLVMTCERISCVIntrinsicsLowering.hh:44
InstructionFormat::encoding
int encoding(const std::string &op) const
Definition: InstructionFormat.cc:200
llvm::LLVMTCERISCVIntrinsicsLowering::findOperationName
std::string findOperationName(const std::string &s) const
Definition: LLVMTCERISCVIntrinsicsLowering.cc:114
LLVMTCERISCVIntrinsicsLowering.hh
OperationPool.hh
BEMGenerator::generate
BinaryEncoding * generate()
Definition: BEMGenerator.cc:104
StringTools::stringToLower
static std::string stringToLower(const std::string &source)
Definition: StringTools.cc:160
CompilerWarnings.hh
TTAMachine::Machine::loadFromADF
static Machine * loadFromADF(const std::string &adfFileName)
Definition: Machine.cc:905