42 #include <llvm/Analysis/LoopInfo.h>
43 #include <llvm/Analysis/LoopPass.h>
45 #include "tce_config.h"
46 #include <llvm/IR/Dominators.h>
48 #include <llvm/Analysis/AliasAnalysis.h>
49 #include <llvm/IR/LegacyPassManager.h>
50 #include <llvm/Pass.h>
52 #include <llvm/CodeGen/AsmPrinter.h>
53 #include <llvm/CodeGen/Passes.h>
55 #include <llvm/Target/TargetMachine.h>
56 #include <llvm/Target/TargetOptions.h>
58 #include <llvm/Transforms/IPO.h>
59 #include <llvm/Transforms/Scalar.h>
61 #include <llvm/Support/CommandLine.h>
62 #include <llvm/Support/FormattedStream.h>
63 #include <llvm/Support/MemoryBuffer.h>
64 #include <llvm/Support/Debug.h>
65 #include <llvm/CodeGen/RegAllocRegistry.h>
67 #include <llvm/IR/Module.h>
68 #include <llvm/IR/LLVMContext.h>
70 #include <llvm/Bitcode/BitcodeReader.h>
72 #include <llvm/IR/Verifier.h>
74 #include <llvm/IR/GCStrategy.h>
76 #include <llvm-c/Core.h>
83 #include "tce_config.h"
85 #include "llvm/MC/TargetRegistry.h"
87 #include "llvm/Support/FileSystem.h"
89 #include <llvm/InitializePasses.h>
124 #define DS TCEString(FileSystem::DIRECTORY_SEPARATOR)
126 using namespace llvm;
128 #include <llvm/IR/IRPrintingPasses.h>
130 #include "llvm/IR/DataLayout.h"
154 requiredOps.insert(
"LD32");
155 requiredOps.insert(
"LD16");
156 requiredOps.insert(
"LDU16");
157 requiredOps.insert(
"LD8");
158 requiredOps.insert(
"LDU8");
159 requiredOps.insert(
"ST32");
160 requiredOps.insert(
"ST16");
161 requiredOps.insert(
"ST8");
163 requiredOps.insert(
"LDW");
164 requiredOps.insert(
"LDH");
165 requiredOps.insert(
"LDHU");
166 requiredOps.insert(
"LDQ");
167 requiredOps.insert(
"LDQU");
168 requiredOps.insert(
"STW");
169 requiredOps.insert(
"STH");
170 requiredOps.insert(
"STQ");
174 if (includeFloatOps) {
175 requiredOps.insert(
"ADDF");
176 requiredOps.insert(
"SUBF");
177 requiredOps.insert(
"MULF");
178 requiredOps.insert(
"DIVF");
179 requiredOps.insert(
"NEGF");
180 requiredOps.insert(
"SQRTF");
182 requiredOps.insert(
"CFI");
183 requiredOps.insert(
"CFIU");
184 requiredOps.insert(
"CIF");
185 requiredOps.insert(
"CIFU");
188 requiredOps.insert(
"EQF");
189 requiredOps.insert(
"NEF");
190 requiredOps.insert(
"LTF");
191 requiredOps.insert(
"LEF");
192 requiredOps.insert(
"GTF");
193 requiredOps.insert(
"GEF");
196 requiredOps.insert(
"EQUF");
197 requiredOps.insert(
"NEUF");
198 requiredOps.insert(
"LTUF");
199 requiredOps.insert(
"LEUF");
200 requiredOps.insert(
"GTUF");
201 requiredOps.insert(
"GEUF");
204 requiredOps.insert(
"ORDF");
205 requiredOps.insert(
"UORDF");
208 requiredOps.insert(
"ADDD");
209 requiredOps.insert(
"SUBD");
210 requiredOps.insert(
"MULD");
211 requiredOps.insert(
"DIVD");
212 requiredOps.insert(
"NEGD");
213 requiredOps.insert(
"SQRTD");
215 requiredOps.insert(
"CDL");
216 requiredOps.insert(
"CDLU");
217 requiredOps.insert(
"CLD");
218 requiredOps.insert(
"CLDU");
220 requiredOps.insert(
"CFD");
221 requiredOps.insert(
"CDF");
224 requiredOps.insert(
"EQD");
225 requiredOps.insert(
"NED");
226 requiredOps.insert(
"LTD");
227 requiredOps.insert(
"LED");
228 requiredOps.insert(
"GTD");
229 requiredOps.insert(
"GED");
232 requiredOps.insert(
"EQUD");
233 requiredOps.insert(
"NEUD");
234 requiredOps.insert(
"LTUD");
235 requiredOps.insert(
"LEUD");
236 requiredOps.insert(
"GTUD");
237 requiredOps.insert(
"GEUD");
240 requiredOps.insert(
"ORDD");
241 requiredOps.insert(
"UORDD");
246 requiredOps.insert(
"LDU32");
247 requiredOps.insert(
"LD64");
248 requiredOps.insert(
"ST64");
250 requiredOps.insert(
"ADD64");
251 requiredOps.insert(
"SUB64");
252 requiredOps.insert(
"MUL64");
253 requiredOps.insert(
"DIV64");
254 requiredOps.insert(
"DIVU64");
255 requiredOps.insert(
"DIV64");
256 requiredOps.insert(
"MOD64");
257 requiredOps.insert(
"MODU64");
259 requiredOps.insert(
"SXH64");
260 requiredOps.insert(
"SXQ64");
262 requiredOps.insert(
"AND64");
263 requiredOps.insert(
"XOR64");
264 requiredOps.insert(
"IOR64");
266 requiredOps.insert(
"SHL64");
267 requiredOps.insert(
"SHR64");
268 requiredOps.insert(
"SHRU64");
270 requiredOps.insert(
"EQ64");
271 requiredOps.insert(
"NE64");
272 requiredOps.insert(
"LT64");
273 requiredOps.insert(
"LTU64");
274 requiredOps.insert(
"LE64");
275 requiredOps.insert(
"LEU64");
276 requiredOps.insert(
"GT64");
277 requiredOps.insert(
"GTU64");
278 requiredOps.insert(
"GE64");
279 requiredOps.insert(
"GEU64");
283 requiredOps.insert(
"ADD");
284 requiredOps.insert(
"SUB");
285 requiredOps.insert(
"MUL");
286 requiredOps.insert(
"DIV");
287 requiredOps.insert(
"DIVU");
288 requiredOps.insert(
"DIV");
289 requiredOps.insert(
"MOD");
290 requiredOps.insert(
"MODU");
292 requiredOps.insert(
"SXHW");
293 requiredOps.insert(
"SXQW");
295 requiredOps.insert(
"AND");
296 requiredOps.insert(
"XOR");
297 requiredOps.insert(
"IOR");
299 requiredOps.insert(
"SHL");
300 requiredOps.insert(
"SHR");
301 requiredOps.insert(
"SHRU");
303 requiredOps.insert(
"EQ");
304 requiredOps.insert(
"NE");
305 requiredOps.insert(
"LT");
306 requiredOps.insert(
"LTU");
307 requiredOps.insert(
"LE");
308 requiredOps.insert(
"LEU");
309 requiredOps.insert(
"GT");
310 requiredOps.insert(
"GTU");
311 requiredOps.insert(
"GE");
312 requiredOps.insert(
"GEU");
325 useInstalledVersion_(useInstalledVersion), tempDir_(tempDir) {
335 PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry();
336 llvm::initializeCore(Registry);
337 llvm::initializeScalarOpts(Registry);
338 llvm::initializeIPO(Registry);
339 llvm::initializeAnalysis(Registry);
340 llvm::initializeTransformUtils(Registry);
341 llvm::initializeInstCombine(Registry);
342 llvm::initializeTarget(Registry);
361 const std::string& bytecodeFile,
const std::string& emulationBytecodeFile,
366 std::set<MachineValidator::ErrorCode> checks;
378 msg += res->
error(i).second +
"\n";
380 delete res; res = NULL;
385 std::string errMsgParse;
388 std::unique_ptr<llvm::Module> m;
390 ErrorOr<std::unique_ptr<MemoryBuffer>> bufferPtr =
391 MemoryBuffer::getFileOrSTDIN(bytecodeFile.c_str());
393 if (std::error_code ec = bufferPtr.getError()) {
394 std::string msg =
"Error reading bytecode file: " + bytecodeFile +
400 std::unique_ptr<MemoryBuffer> buffer = std::move(bufferPtr.get());
401 Expected<std::unique_ptr<llvm::Module> > module =
402 parseBitcodeFile(buffer.get()->getMemBufferRef(), context);
403 if (Error E = module.takeError()) {
410 m = std::move(module.get());
413 std::string msg =
"Error parsing bytecode file: " + bytecodeFile +
418 std::unique_ptr<Module> emuM;
420 if (!emulationBytecodeFile.empty()) {
421 ErrorOr<std::unique_ptr<MemoryBuffer>> emuBufferPtr =
422 MemoryBuffer::getFileOrSTDIN(emulationBytecodeFile.c_str());
424 if (std::error_code ec = emuBufferPtr.getError()) {
425 std::string msg =
"Error reading bytecode file: " +
426 emulationBytecodeFile +
427 " of emulation library:\n" + ec.message();
431 std::unique_ptr<MemoryBuffer> emuBuffer =
432 std::move(emuBufferPtr.get());
433 Expected<std::unique_ptr<Module> > module =
434 parseBitcodeFile(emuBuffer.get()->getMemBufferRef(), context);
435 if (Error E = module.takeError()) {
437 emulationBytecodeFile +
" of emulation library \n"
441 emuM = std::move(module.get());
442 if (emuM.get() == 0) {
443 std::string msg =
"Error parsing bytecode file: " +
444 emulationBytecodeFile +
" of emulation library \n"
451 #if (!defined(HAVE_CXX11) && !defined(HAVE_CXX0X))
452 std::auto_ptr<TCETargetMachinePlugin> plugin(
createPlugin(target));
454 std::unique_ptr<TCETargetMachinePlugin> plugin(
createPlugin(target));
461 compile(*m.release(), emuM.release(), *plugin, target, optLevel,
472 delete res; res = NULL;
485 delete res; res = NULL;
510 unsigned maxAlignment = 4;
511 for (llvm::Module::const_iterator f = mod.begin(),
512 fe = mod.end(); f != fe; ++f) {
513 for (llvm::Function::const_iterator bb = f->begin(), be = f->end();
515 const llvm::BasicBlock* basicBlock = &(*bb);
516 for (llvm::BasicBlock::const_iterator i = basicBlock->begin(),
517 ie = basicBlock->end(); i != ie; ++i) {
518 if (!isa<const llvm::AllocaInst>(i))
continue;
519 const llvm::AllocaInst* alloca =
520 dyn_cast<const llvm::AllocaInst>(i);
521 #ifdef LLVM_OLDER_THAN_15
522 maxAlignment = std::max(maxAlignment,
523 (
unsigned)alloca->getAlign().value());
524 maxAlignment = std::max(maxAlignment,
525 (
unsigned)alloca->getAlignment());
527 maxAlignment = std::max(maxAlignment,
528 (
unsigned)alloca->getAlign().value());
529 maxAlignment = std::max(maxAlignment,
530 (
unsigned)alloca->getAlign().value());
539 static MCRegisterInfo*
541 MCRegisterInfo*
X =
new MCRegisterInfo();
547 MCInstrInfo*
X =
new MCInstrInfo();
551 static MCSubtargetInfo*
553 const MCWriteProcResEntry WPR[] = {{0, 0}};
554 const MCWriteLatencyEntry WL[] = {{0, 0}};
555 const MCReadAdvanceEntry
RA[] = {{0, 0, 0}};
556 ArrayRef<SubtargetFeatureKV> PF;
557 ArrayRef<SubtargetSubTypeKV> PD;
559 MCSubtargetInfo*
X =
new MCSubtargetInfo(
560 TT, CPU,
"", FS, PF, PD, WPR, WL,
RA,
nullptr,
nullptr,
579 llvm::Module& module, llvm::Module* emulationModule,
584 std::string targetStr =
"tce-llvm";
587 targetStr =
"tcele64-llvm";
589 targetStr =
"tcele-llvm";
593 std::string errorStr;
595 std::string featureString =
"";
611 const Target* tceTarget =
612 TargetRegistry::lookupTarget(targetStr, errorStr);
613 Target* nonconst_target =
const_cast<Target*
>(tceTarget);
616 errs() << errorStr <<
"\n";
620 TargetRegistry::RegisterMCRegInfo(
622 TargetRegistry::RegisterMCInstrInfo(
624 TargetRegistry::RegisterMCSubtargetInfo(
627 std::string cpuStr =
"tce";
633 Options.HonorSignDependentRoundingFPMathOption =
false;
640 module.setOverrideStackAlignment(maxMachineAlignment);
645 "Alloca object requires larger stack alignment than widest "
647 "We were hoping this wouldn't happen, because now stack "
648 "alignment cannot be "
649 "figured out just from adf-file. ATM (5/20) this assumption is "
651 "at tcecc::getStackAlignment and at CodeGenerator.cc "
655 module.setOverrideStackAlignment(
658 Options.GuaranteedTailCallOpt =
true;
662 tceTarget->createTargetMachine(
663 targetStr, cpuStr, featureString,
Options,
664 Reloc::Model::Static));
666 if (!targetMachine) {
667 errs() <<
"Could not create tce target machine" <<
"\n";
675 std::max((
unsigned)(target.
is64bit() ? 8 : 4),
676 module.getOverrideStackAlignment()));
687 llvm::legacy::PassManager Passes;
688 #define addPass(P) Passes.add(P)
690 llvm::raw_fd_ostream sos(STDOUT_FILENO,
false);
692 targetMachine->addPassesToEmitFile(
693 Passes, sos,
nullptr, CGFT_AssemblyFile);
698 ImmutablePass* (*creator)();
703 "create_workitem_aa_plugin", creator, file);
705 std::string msg = std::string() +
706 "Unable to load plugin file '" +
712 "Most likely too old version of POCL. \
713 TCE will continue without work item alias analysis." <<
741 for (
unsigned int i = 0; i < paramRegs.size(); i++) {
743 p->first = plugin.
rfName(paramRegs[i]);
751 for (
unsigned int i = 0; i < vectorRVRegs.size(); i++) {
753 p->first = plugin.
rfName(vectorRVRegs[i]);
769 llvm::legacy::PassManager FPasses;
771 FPasses.add(loopFinder);
811 std::string pluginFileName;
812 std::string tempPluginFileName;
820 tempPluginFileName =
cachePath_ +
DS + pluginFile +
".%%_%%_%%_%%";
822 llvm::SmallString<128> ResultPath;
823 llvm::sys::fs::createUniqueFile(llvm::Twine(tempPluginFileName), ResultPath);
824 tempPluginFileName = ResultPath.str().str();
827 std::string srcsPath =
"";
828 std::string pluginIncludeFlags =
"";
831 pluginIncludeFlags =
" -I" + srcsPath;
833 srcsPath = std::string(TCE_SRC_ROOT) +
DS +
834 "src" +
DS +
"applibs" +
DS +
"LLVMBackend" +
DS +
"plugin" +
DS;
838 " -I" + std::string(TCE_SRC_ROOT) +
DS +
" " +
839 " -I" + std::string(TCE_SRC_ROOT) +
DS +
"src" +
DS +
"tools" +
840 " -I" + std::string(TCE_SRC_ROOT) +
DS +
"src" +
DS +
"base" +
842 " -I" + std::string(TCE_SRC_ROOT) +
DS +
"src" +
DS +
843 "applibs" +
DS +
"LLVMBackend" +
DS +
" " +
845 " -I" + std::string(TCE_SRC_ROOT) +
DS +
"src" +
DS +
846 "applibs" +
DS +
"mach" +
" " +
848 " -I" + std::string(TCE_SRC_ROOT) +
DS +
"src" +
DS +
849 "applibs" +
DS +
"Scheduler" +
DS +
" " +
851 " -I" + std::string(TCE_SRC_ROOT) +
DS +
"src" +
DS +
852 "applibs" +
DS +
"Scheduler" +
DS +
"Algorithms" +
" " +
854 " -I`" LLVM_CONFIG
" --includedir`" +
DS +
"llvm" +
DS +
868 "create_tce_backend_plugin", creator, pluginFile);
874 <<
"Unable to load plugin file " << pluginFileName
876 <<
"regenerating..." << std::endl;
890 "Failed to build compiler plugin for target architecture: ";
897 std::string tblgenbin =
"llvm-tblgen";
900 std::string tblgenCmd;
907 if (system(LLVM_CONFIG
" --version")) {
908 std::string msg =
"Unable to determine llvm include dir. "
909 LLVM_CONFIG
" not found in path";
918 " -I`" LLVM_CONFIG
" --includedir`" +
919 " -I`" LLVM_CONFIG
" --includedir`/Target" +
920 " -I`" LLVM_CONFIG
" --includedir`/llvm/Target" +
926 " -I" + LLVM_INCLUDE_DIR +
927 " -I" + LLVM_INCLUDE_DIR +
"/Target" +
928 " -I" + LLVM_INCLUDE_DIR +
"/llvm/Target";
934 std::string cmd = tblgenCmd +
935 " -gen-register-info" +
937 "TCEGenRegisterInfo.inc";
942 int ret = system(cmd.c_str());
944 std::string msg = std::string() +
945 "Failed to build compiler plugin for target architecture.\n" +
946 "Failed command was: " + cmd;
955 "TCEGenInstrInfo.inc";
957 ret = system(cmd.c_str());
959 std::string msg = std::string() +
960 "Failed to build compiler plugin for target architecture.\n" +
961 "Failed command was: " + cmd;
972 ret = system(cmd.c_str());
974 std::string msg = std::string() +
975 "Failed to build compiler plugin for target architecture.\n" +
976 "Failed command was: " + cmd;
984 " -gen-callingconv" +
986 "TCEGenCallingConv.inc";
988 ret = system(cmd.c_str());
990 std::string msg = std::string() +
991 "Failed to build compiler plugin for target architecture.\n" +
992 "Failed command was: " + cmd;
1001 "TCEGenSubTargetInfo.inc";
1003 ret = system(cmd.c_str());
1007 "Failed to build compiler plugin for target architecture.\n" +
1008 "Failed command was: " + cmd;
1014 cmd = tblgenCmd +
" -gen-dfa-packetizer" +
" -o " +
tempDir_ +
1017 ret = system(cmd.c_str());
1021 "Failed to build compiler plugin for target architecture.\n" +
1022 "Failed command was: " + cmd;
1028 TCEString pluginSources = srcsPath +
"PluginCompileWrapper.cc ";
1031 "-DLITTLE_ENDIAN_TARGET" :
"";
1036 cmd = std::string(CXX) +
1038 pluginIncludeFlags +
1039 " " + SHARED_CXX_FLAGS +
1040 " " + LLVM_CPPFLAGS;
1043 cmd +=
" -I`" LLVM_CONFIG
" --includedir`";
1047 " " + endianOption +
1048 " " + bitnessOption +
1049 " " + pluginSources +
1050 " -o " + tempPluginFileName;
1055 ret = system(cmd.c_str());
1057 std::string msg = std::string() +
1058 "Failed to build compiler plugin for target architecture.\n" +
1059 "Failed command was: " + cmd;
1065 llvm::sys::fs::rename(llvm::Twine(tempPluginFileName), llvm::Twine(pluginFileName));
1073 "create_tce_backend_plugin", creator, pluginFile);
1075 std::string msg = std::string() +
1076 "Unable to load plugin file '" +