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>
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)
128#include <llvm/IR/IRPrintingPasses.h>
130#include "llvm/IR/DataLayout.h"
155 requiredOps.insert(
"LD32");
156 requiredOps.insert(
"LD16");
157 requiredOps.insert(
"LDU16");
158 requiredOps.insert(
"LD8");
159 requiredOps.insert(
"LDU8");
160 requiredOps.insert(
"ST32");
161 requiredOps.insert(
"ST16");
162 requiredOps.insert(
"ST8");
164 requiredOps.insert(
"LDW");
165 requiredOps.insert(
"LDH");
166 requiredOps.insert(
"LDHU");
167 requiredOps.insert(
"LDQ");
168 requiredOps.insert(
"LDQU");
169 requiredOps.insert(
"STW");
170 requiredOps.insert(
"STH");
171 requiredOps.insert(
"STQ");
175 if (includeFloatOps) {
176 requiredOps.insert(
"ADDF");
177 requiredOps.insert(
"SUBF");
178 requiredOps.insert(
"MULF");
179 requiredOps.insert(
"DIVF");
180 requiredOps.insert(
"NEGF");
181 requiredOps.insert(
"SQRTF");
183 requiredOps.insert(
"CFI");
184 requiredOps.insert(
"CFIU");
185 requiredOps.insert(
"CIF");
186 requiredOps.insert(
"CIFU");
189 requiredOps.insert(
"EQF");
190 requiredOps.insert(
"NEF");
191 requiredOps.insert(
"LTF");
192 requiredOps.insert(
"LEF");
193 requiredOps.insert(
"GTF");
194 requiredOps.insert(
"GEF");
197 requiredOps.insert(
"EQUF");
198 requiredOps.insert(
"NEUF");
199 requiredOps.insert(
"LTUF");
200 requiredOps.insert(
"LEUF");
201 requiredOps.insert(
"GTUF");
202 requiredOps.insert(
"GEUF");
205 requiredOps.insert(
"ORDF");
206 requiredOps.insert(
"UORDF");
209 requiredOps.insert(
"ADDD");
210 requiredOps.insert(
"SUBD");
211 requiredOps.insert(
"MULD");
212 requiredOps.insert(
"DIVD");
213 requiredOps.insert(
"NEGD");
214 requiredOps.insert(
"SQRTD");
216 requiredOps.insert(
"CDL");
217 requiredOps.insert(
"CDLU");
218 requiredOps.insert(
"CLD");
219 requiredOps.insert(
"CLDU");
221 requiredOps.insert(
"CFD");
222 requiredOps.insert(
"CDF");
225 requiredOps.insert(
"EQD");
226 requiredOps.insert(
"NED");
227 requiredOps.insert(
"LTD");
228 requiredOps.insert(
"LED");
229 requiredOps.insert(
"GTD");
230 requiredOps.insert(
"GED");
233 requiredOps.insert(
"EQUD");
234 requiredOps.insert(
"NEUD");
235 requiredOps.insert(
"LTUD");
236 requiredOps.insert(
"LEUD");
237 requiredOps.insert(
"GTUD");
238 requiredOps.insert(
"GEUD");
241 requiredOps.insert(
"ORDD");
242 requiredOps.insert(
"UORDD");
247 requiredOps.insert(
"LDU32");
248 requiredOps.insert(
"LD64");
249 requiredOps.insert(
"ST64");
251 requiredOps.insert(
"ADD64");
252 requiredOps.insert(
"SUB64");
253 requiredOps.insert(
"MUL64");
254 requiredOps.insert(
"DIV64");
255 requiredOps.insert(
"DIVU64");
256 requiredOps.insert(
"DIV64");
257 requiredOps.insert(
"MOD64");
258 requiredOps.insert(
"MODU64");
260 requiredOps.insert(
"SXH64");
261 requiredOps.insert(
"SXQ64");
263 requiredOps.insert(
"AND64");
264 requiredOps.insert(
"XOR64");
265 requiredOps.insert(
"IOR64");
267 requiredOps.insert(
"SHL64");
268 requiredOps.insert(
"SHR64");
269 requiredOps.insert(
"SHRU64");
271 requiredOps.insert(
"EQ64");
272 requiredOps.insert(
"NE64");
273 requiredOps.insert(
"LT64");
274 requiredOps.insert(
"LTU64");
275 requiredOps.insert(
"LE64");
276 requiredOps.insert(
"LEU64");
277 requiredOps.insert(
"GT64");
278 requiredOps.insert(
"GTU64");
279 requiredOps.insert(
"GE64");
280 requiredOps.insert(
"GEU64");
284 requiredOps.insert(
"ADD");
285 requiredOps.insert(
"SUB");
286 requiredOps.insert(
"MUL");
287 requiredOps.insert(
"DIV");
288 requiredOps.insert(
"DIVU");
289 requiredOps.insert(
"DIV");
290 requiredOps.insert(
"MOD");
291 requiredOps.insert(
"MODU");
293 requiredOps.insert(
"SXHW");
294 requiredOps.insert(
"SXQW");
296 requiredOps.insert(
"AND");
297 requiredOps.insert(
"XOR");
298 requiredOps.insert(
"IOR");
300 requiredOps.insert(
"SHL");
301 requiredOps.insert(
"SHR");
302 requiredOps.insert(
"SHRU");
304 requiredOps.insert(
"EQ");
305 requiredOps.insert(
"NE");
306 requiredOps.insert(
"LT");
307 requiredOps.insert(
"LTU");
308 requiredOps.insert(
"LE");
309 requiredOps.insert(
"LEU");
310 requiredOps.insert(
"GT");
311 requiredOps.insert(
"GTU");
312 requiredOps.insert(
"GE");
313 requiredOps.insert(
"GEU");
326 useInstalledVersion_(useInstalledVersion), tempDir_(tempDir), mach_(NULL),
337 PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry();
338 llvm::initializeCore(Registry);
339 llvm::initializeScalarOpts(Registry);
340 llvm::initializeIPO(Registry);
341 llvm::initializeAnalysis(Registry);
342 llvm::initializeTransformUtils(Registry);
343 llvm::initializeInstCombine(Registry);
344 llvm::initializeTarget(Registry);
382 const std::string& bytecodeFile,
const std::string& emulationBytecodeFile,
385 assert(
mach_ != NULL &&
"Machine not set, forgot to call setMachine()?");
388 std::set<MachineValidator::ErrorCode> checks;
400 msg += res->
error(i).second +
"\n";
402 delete res; res = NULL;
407 std::string errMsgParse;
410 std::unique_ptr<llvm::Module> m;
412 ErrorOr<std::unique_ptr<MemoryBuffer>> bufferPtr =
413 MemoryBuffer::getFileOrSTDIN(bytecodeFile.c_str());
415 if (std::error_code ec = bufferPtr.getError()) {
416 std::string msg =
"Error reading bytecode file: " + bytecodeFile +
422 std::unique_ptr<MemoryBuffer> buffer = std::move(bufferPtr.get());
423 Expected<std::unique_ptr<llvm::Module> >
module =
424 parseBitcodeFile(buffer.get()->getMemBufferRef(), context);
425 if (Error E = module.takeError()) {
432 m = std::move(module.get());
435 std::string msg =
"Error parsing bytecode file: " + bytecodeFile +
440 std::unique_ptr<Module> emuM;
442 if (!emulationBytecodeFile.empty()) {
443 ErrorOr<std::unique_ptr<MemoryBuffer>> emuBufferPtr =
444 MemoryBuffer::getFileOrSTDIN(emulationBytecodeFile.c_str());
446 if (std::error_code ec = emuBufferPtr.getError()) {
447 std::string msg =
"Error reading bytecode file: " +
448 emulationBytecodeFile +
449 " of emulation library:\n" + ec.message();
453 std::unique_ptr<MemoryBuffer> emuBuffer =
454 std::move(emuBufferPtr.get());
455 Expected<std::unique_ptr<Module> >
module =
456 parseBitcodeFile(emuBuffer.get()->getMemBufferRef(), context);
457 if (Error E = module.takeError()) {
459 emulationBytecodeFile +
" of emulation library \n"
463 emuM = std::move(module.get());
464 if (emuM.get() == 0) {
465 std::string msg =
"Error parsing bytecode file: " +
466 emulationBytecodeFile +
" of emulation library \n"
473#if (!defined(HAVE_CXX11) && !defined(HAVE_CXX0X))
474 std::auto_ptr<TCETargetMachinePlugin> plugin(
createPlugin());
476 std::unique_ptr<TCETargetMachinePlugin> plugin(
createPlugin());
483 compile(*m.release(), emuM.release(), *plugin, optLevel,
494 delete res; res = NULL;
507 delete res; res = NULL;
532 unsigned maxAlignment = 4;
533 for (llvm::Module::const_iterator f = mod.begin(),
534 fe = mod.end(); f != fe; ++f) {
535 for (llvm::Function::const_iterator bb = f->begin(), be = f->end();
537 const llvm::BasicBlock* basicBlock = &(*bb);
538 for (llvm::BasicBlock::const_iterator i = basicBlock->begin(),
539 ie = basicBlock->end(); i != ie; ++i) {
540 if (!isa<const llvm::AllocaInst>(i))
continue;
541 const llvm::AllocaInst* alloca =
542 dyn_cast<const llvm::AllocaInst>(i);
543 #ifdef LLVM_OLDER_THAN_15
544 maxAlignment = std::max(maxAlignment,
545 (
unsigned)alloca->getAlign().value());
546 maxAlignment = std::max(maxAlignment,
547 (
unsigned)alloca->getAlignment());
549 maxAlignment = std::max(maxAlignment,
550 (
unsigned)alloca->getAlign().value());
551 maxAlignment = std::max(maxAlignment,
552 (
unsigned)alloca->getAlign().value());
561static MCRegisterInfo*
563 MCRegisterInfo*
X =
new MCRegisterInfo();
569 MCInstrInfo*
X =
new MCInstrInfo();
573static MCSubtargetInfo*
575 const MCWriteProcResEntry WPR[] = {{0, 0}};
576 const MCWriteLatencyEntry WL[] = {{0, 0}};
577 const MCReadAdvanceEntry
RA[] = {{0, 0, 0}};
578 ArrayRef<SubtargetFeatureKV> PF;
579 ArrayRef<SubtargetSubTypeKV> PD;
581 MCSubtargetInfo*
X =
new MCSubtargetInfo(
582 TT, CPU,
"", FS, PF, PD, WPR, WL,
RA,
nullptr,
nullptr,
600 llvm::Module& module, llvm::Module* emulationModule,
603 assert(
mach_ != NULL &&
"Machine not set, forgot to call setMachine()?");
606 std::string targetStr =
"tce-llvm";
609 targetStr =
"tcele64-llvm";
611 targetStr =
"tcele-llvm";
615 std::string errorStr;
617 std::string featureString =
"";
633 const Target* tceTarget =
634 TargetRegistry::lookupTarget(targetStr, errorStr);
635 Target* nonconst_target =
const_cast<Target*
>(tceTarget);
638 errs() << errorStr <<
"\n";
642 TargetRegistry::RegisterMCRegInfo(
644 TargetRegistry::RegisterMCInstrInfo(
646 TargetRegistry::RegisterMCSubtargetInfo(
649 std::string cpuStr =
"tce";
655 Options.HonorSignDependentRoundingFPMathOption =
false;
662 module.setOverrideStackAlignment(maxMachineAlignment);
667 "Alloca object requires larger stack alignment than widest "
669 "We were hoping this wouldn't happen, because now stack "
670 "alignment cannot be "
671 "figured out just from adf-file. ATM (5/20) this assumption is "
673 "at tcecc::getStackAlignment and at CodeGenerator.cc "
677 module.setOverrideStackAlignment(
678 std::max(maxMachineAlignment, maxAllocaAlignment(module)));
680 Options.GuaranteedTailCallOpt =
true;
684 tceTarget->createTargetMachine(
685 targetStr, cpuStr, featureString,
Options,
686 Reloc::Model::Static));
688 if (!targetMachine) {
689 errs() <<
"Could not create tce target machine" <<
"\n";
698 module.getOverrideStackAlignment()));
709 llvm::legacy::PassManager Passes;
710#define addPass(P) Passes.add(P)
712 llvm::raw_fd_ostream sos(STDOUT_FILENO,
false);
714 targetMachine->addPassesToEmitFile(
715 Passes, sos,
nullptr, CGFT_AssemblyFile);
720 ImmutablePass* (*creator)();
725 "create_workitem_aa_plugin", creator, file);
727 std::string msg = std::string() +
728 "Unable to load plugin file '" +
734 "Most likely too old version of POCL. \
735 TCE will continue without work item alias analysis." <<
763 for (
unsigned int i = 0; i < paramRegs.size(); i++) {
765 p->first = plugin.
rfName(paramRegs[i]);
773 for (
unsigned int i = 0; i < vectorRVRegs.size(); i++) {
775 p->first = plugin.
rfName(vectorRVRegs[i]);
791 llvm::legacy::PassManager FPasses;
793 FPasses.add(loopFinder);
830 assert(
mach_ != NULL &&
"Machine not set, forgot to call setMachine()?");
832 std::string pluginFileName;
841 llvm::SmallString<128> ResultPath;
844 std::string srcsPath =
"";
845 std::string pluginIncludeFlags =
"";
848 pluginIncludeFlags =
" -I" + srcsPath;
850 srcsPath = std::string(TCE_SRC_ROOT) +
DS +
851 "src" +
DS +
"applibs" +
DS +
"LLVMBackend" +
DS +
"plugin" +
DS;
855 " -I" + std::string(TCE_SRC_ROOT) +
DS +
" " +
856 " -I" + std::string(TCE_SRC_ROOT) +
DS +
"src" +
DS +
"tools" +
857 " -I" + std::string(TCE_SRC_ROOT) +
DS +
"src" +
DS +
"base" +
859 " -I" + std::string(TCE_SRC_ROOT) +
DS +
"src" +
DS +
860 "applibs" +
DS +
"LLVMBackend" +
DS +
" " +
862 " -I" + std::string(TCE_SRC_ROOT) +
DS +
"src" +
DS +
863 "applibs" +
DS +
"mach" +
" " +
865 " -I" + std::string(TCE_SRC_ROOT) +
DS +
"src" +
DS +
866 "applibs" +
DS +
"Scheduler" +
DS +
" " +
868 " -I" + std::string(TCE_SRC_ROOT) +
DS +
"src" +
DS +
869 "applibs" +
DS +
"Scheduler" +
DS +
"Algorithms" +
" " +
871 " -I`" LLVM_CONFIG
" --includedir`" +
DS +
"llvm" +
DS +
885 "create_tce_backend_plugin", creator, pluginFile);
891 <<
"Unable to load plugin file " << pluginFileName
893 <<
"regenerating..." << std::endl;
906 "Failed to build compiler plugin for target architecture: ";
913 std::string tblgenbin =
"llvm-tblgen";
916 std::string tblgenCmd;
923 if (system(LLVM_CONFIG
" --version")) {
924 std::string msg =
"Unable to determine llvm include dir. "
925 LLVM_CONFIG
" not found in path";
934 " -I`" LLVM_CONFIG
" --includedir`" +
935 " -I`" LLVM_CONFIG
" --includedir`/Target" +
936 " -I`" LLVM_CONFIG
" --includedir`/llvm/Target" +
942 " -I" + LLVM_INCLUDE_DIR +
943 " -I" + LLVM_INCLUDE_DIR +
"/Target" +
944 " -I" + LLVM_INCLUDE_DIR +
"/llvm/Target";
950 std::string cmd = tblgenCmd +
951 " -gen-register-info" +
953 "TCEGenRegisterInfo.inc";
958 int ret = system(cmd.c_str());
960 std::string msg = std::string() +
961 "Failed to build compiler plugin for target architecture.\n" +
962 "Failed command was: " + cmd;
971 "TCEGenInstrInfo.inc";
973 ret = system(cmd.c_str());
975 std::string msg = std::string() +
976 "Failed to build compiler plugin for target architecture.\n" +
977 "Failed command was: " + cmd;
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;
1000 " -gen-callingconv" +
1002 "TCEGenCallingConv.inc";
1004 ret = system(cmd.c_str());
1006 std::string msg = std::string() +
1007 "Failed to build compiler plugin for target architecture.\n" +
1008 "Failed command was: " + cmd;
1017 "TCEGenSubTargetInfo.inc";
1019 ret = system(cmd.c_str());
1023 "Failed to build compiler plugin for target architecture.\n" +
1024 "Failed command was: " + cmd;
1030 cmd = tblgenCmd +
" -gen-dfa-packetizer" +
" -o " +
tempDir_ +
1033 ret = system(cmd.c_str());
1037 "Failed to build compiler plugin for target architecture.\n" +
1038 "Failed command was: " + cmd;
1044 TCEString pluginSources = srcsPath +
"PluginCompileWrapper.cc ";
1047 "-DLITTLE_ENDIAN_TARGET" :
"";
1051 std::string tempPluginFileName;
1052 tempPluginFileName =
cachePath_ +
DS + pluginFile +
".%%_%%_%%_%%";
1053 llvm::sys::fs::createUniqueFile(llvm::Twine(tempPluginFileName), ResultPath);
1054 tempPluginFileName = ResultPath.str().str();
1057 cmd = std::string(CXX) +
1059 pluginIncludeFlags +
1060 " " + SHARED_CXX_FLAGS +
1061 " " + LLVM_CPPFLAGS;
1064 cmd +=
" -I`" LLVM_CONFIG
" --includedir`";
1067 #ifdef LLVM_OLDER_THAN_16
1072 " " + endianOption +
1073 " " + bitnessOption +
1074 " " + pluginSources +
1075 " -o " + tempPluginFileName;
1080 ret = system(cmd.c_str());
1082 std::string msg = std::string() +
1083 "Failed to build compiler plugin for target architecture.\n" +
1084 "Failed command was: " + cmd;
1090 llvm::sys::fs::rename(llvm::Twine(tempPluginFileName), llvm::Twine(pluginFileName));
1098 "create_tce_backend_plugin", creator, pluginFile);
1100 std::string msg = std::string() +
1101 "Unable to load plugin file '" +
1123 "TDPlugin not set, forgot to call setMachine()?");
1127 boost::hash<std::string> stringHasher;
1128 size_t h = stringHasher(buffer);
#define abortWithError(message)
#define assert(condition)
#define IGNORE_COMPILER_WARNING(X)
#define POP_COMPILER_DIAGS
#define THROW_EXCEPTION(exceptionType, message)
Exception wrapper macro that automatically includes file name, line number and function name where th...
static llvm::RegisterPass< InnerLoopFinder > X("find-innerloops-test", "Finds inner loops test.", false, true)
SimpleInterPassDatum< std::pair< TCEString, unsigned int > > RegDatum
Datum type for transferring register name as a data. Stack pointer register is saved with key STACK_P...
Pass * createWorkItemAliasAnalysisPass()
static MCSubtargetInfo * createTCEMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS)
llvm::DataLayout TargetData
static MCRegisterInfo * createTCEMCRegisterInfo(const Triple &TT)
static MCInstrInfo * createTCEMCInstrInfo()
void LLVMInitializeTCETargetInfo()
void LLVMInitializeTCETarget()
static CmdLineOptions * cmdLineOptions()
static std::string installationDir()
static std::string TCEVersionString()
static int verboseLevel()
static std::ostream & logStream()
static std::string toHexString(T source, std::size_t digits=0, bool include0x=true)
static std::string llvmtceCachePath()
std::string errorMessageStack(bool messagesOnly=false) const
std::string errorMessage() const
void setCause(const Exception &cause)
static bool fileIsReadable(const std::string fileName)
static bool createDirectory(const std::string &path)
static bool removeFileOrDirectory(const std::string &path)
static const std::string DIRECTORY_SEPARATOR
static bool fileIsDirectory(const std::string fileName)
static bool fileExists(const std::string fileName)
void setDatum(const std::string &key, InterPassDatum *datum)
LLVMTCECmdLineOptions * options_
static const std::string PLUGIN_PREFIX
static const std::string PLUGIN_SUFFIX
bool useInstalledVersion_
Assume we are running an installed TCE version.
static const TCEString CXX17_FLAG
llvm::TCETargetMachinePlugin * createPlugin()
TCEString cachePath_
Path to the cache where precompiled plugins are stored.
LLVMBackend(bool useInstalledVersion, TCEString tempDir)
std::string pluginFilename()
TTAProgram::Program * compile(const std::string &bytecodeFile, const std::string &emulationBytecodeFile, int optLevel, bool debug=false, InterPassData *ipData=NULL)
static const std::string TBLGEN_INCLUDES
PluginTools pluginTool_
Plugin tool for loading target machine plugin.
TCEString tempDir_
Directory to store temporary files.
unsigned maxAllocaAlignment(const llvm::Module &mod) const
static OperationDAGSelector::OperationSet llvmRequiredOpset(bool includeFloatOps, bool isLittleEndian, bool bits64)
TTAMachine::Machine * mach_
void setMachine(TTAMachine::Machine &target)
static const TCEString CXX14_FLAG
static const TCEString CXX0X_FLAG
static const TCEString CXX11_FLAG
uint64_t initialStackPointerValue() const
bool useOldBackendSources() const
bool isInitialStackPointerValueSet() const
bool assumeADFStackAlignment() const
bool saveBackendPlugin() const
std::string workItemAAFile() const
bool isWorkItemAAFileDefined() const
std::string backendCacheDir() const
static int maxMemoryAlignment(const TTAMachine::Machine &mach)
Error error(int index) const
MachineValidatorResults * validate(const std::set< ErrorCode > &errorsToCheck) const
@ GCU_AS_MISSING
Address space missing in GCU.
@ RA_PORT_MISSING
RA port missing in GCU.
@ FU_PORT_MISSING
FU is missing ports.
@ USED_IO_NOT_BOUND
Pipeline uses an IO which is not bound.
@ GCU_MISSING
GCU missing in machine.
@ PC_PORT_MISSING
PC port missing in GCU.
TCETools::CIStringSet OperationSet
virtual void generateBackend(const std::string &path) const
bool isLittleEndian() const
bool isProgramUsingRestrictedPointers() const
TTAProgram::Program * result()
void deleteDeadProcedures()
void setInitialStackPointerValue(unsigned value)
void setInnerLoopFinder(InnerLoopFinder *loopFinder)
virtual std::vector< unsigned > getParamDRegNums() const =0
virtual std::string rfName(unsigned dwarfRegNum)=0
Returns name of the physical register file corresponding to a generated register ID.
virtual std::vector< unsigned > getVectorRVDRegNums() const =0
virtual unsigned registerIndex(unsigned dwarfRegNum)=0
Returns name of the physical register index corresponding to a generated register ID.
virtual unsigned rvDRegNum()=0
virtual unsigned spDRegNum()=0
Returns ID number of the stack pointer register.
virtual unsigned fpDRegNum()=0
Returns ID number of the frame pointer register.
virtual void setEmulationModule(Module *mod)
void setStackAlignment(unsigned align)
virtual void setTargetMachinePlugin(TCETargetMachinePlugin &plugin, TTAMachine::Machine &target)