source: icGREP/icgrep-devel/icgrep/IR_Gen/llvm2ptx.h @ 5461

Last change on this file since 5461 was 5461, checked in by lindanl, 2 years ago

Optimize compilation for NVPTX driver.

File size: 4.1 KB
Line 
1#ifndef LLVM2PTX_H
2#define LLVM2PTX_H
3
4#include "llvm/Analysis/TargetLibraryInfo.h"
5#include "llvm/CodeGen/CommandFlags.h"
6#include "llvm/CodeGen/MIRParser/MIRParser.h"
7#include "llvm/IR/LegacyPassManager.h"
8#include "llvm/IR/Module.h"
9#include "llvm/IR/Verifier.h"
10#include "llvm/IRReader/IRReader.h"
11#include "llvm/Support/CommandLine.h"
12#include "llvm/Support/FileSystem.h"
13#include "llvm/Support/SourceMgr.h"
14#include "llvm/Support/TargetRegistry.h"
15#include "llvm/Support/TargetSelect.h"
16#include "llvm/Support/ToolOutputFile.h"
17#include "llvm/Target/TargetMachine.h"
18#include <memory>
19using namespace llvm;
20
21static int llvm2ptx(Module * M, std::string PTXFilename) {
22
23  LLVMContext Context;
24  SMDiagnostic Err;
25  std::unique_ptr<MIRParser> MIR;
26  Triple TheTriple;
27
28#ifndef NDEBUG
29  if (verifyModule(*M, &errs())) {
30    errs() << IRFilename << ": error: input module is broken!\n";
31    return 1;
32  }
33#endif
34
35  TheTriple = Triple(M->getTargetTriple());
36
37  if (TheTriple.getTriple().empty())
38    TheTriple.setTriple(sys::getDefaultTargetTriple());
39
40  // Get the target specific parser.
41  std::string Error;
42  const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple,
43                                                         Error);
44  if (!TheTarget) {
45    errs() << Error;
46    return 1;
47  }
48
49  std::string CPUStr = getCPUStr(), FeaturesStr = getFeaturesStr();
50
51  CodeGenOpt::Level OLvl = CodeGenOpt::Default;
52
53  TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
54
55  std::unique_ptr<TargetMachine> Target(
56      TheTarget->createTargetMachine(TheTriple.getTriple(), CPUStr, FeaturesStr,
57                                     Options, RelocModel, CMModel, OLvl));
58
59  assert(Target && "Could not allocate target machine!");
60
61  // Figure out where we are going to send the output.
62  std::error_code EC;
63  sys::fs::OpenFlags OpenFlags = sys::fs::F_None | sys::fs::F_Text;
64  std::unique_ptr<tool_output_file> Out = llvm::make_unique<tool_output_file>(PTXFilename, EC, OpenFlags);
65  if (EC) {
66    errs() << EC.message() << '\n';
67    return 1;
68  }
69
70  // Build up all of the passes that we want to do to the module.
71  legacy::PassManager PM;
72
73  // Add an appropriate TargetLibraryInfo pass for the module's triple.
74  TargetLibraryInfoImpl TLII(Triple(M->getTargetTriple()));
75
76  PM.add(new TargetLibraryInfoWrapperPass(TLII));
77
78  // Add the target data from the target machine, if it exists, or the module.
79  M->setDataLayout(Target->createDataLayout());
80
81  // Override function attributes based on CPUStr, FeaturesStr, and command line
82  // flags.
83  setFunctionAttributes(CPUStr, FeaturesStr, *M);
84
85  {
86    raw_pwrite_stream *OS = &Out->os();
87
88    AnalysisID StartBeforeID = nullptr;
89    AnalysisID StartAfterID = nullptr;
90    AnalysisID StopAfterID = nullptr;
91    const PassRegistry *PR = PassRegistry::getPassRegistry();
92    if (!RunPass.empty()) {
93      if (!StartAfter.empty() || !StopAfter.empty()) {
94        errs() << "start-after and/or stop-after passes are redundant when run-pass is specified.\n";
95        return 1;
96      }
97      const PassInfo *PI = PR->getPassInfo(RunPass);
98      if (!PI) {
99        errs() << "run-pass pass is not registered.\n";
100        return 1;
101      }
102      StopAfterID = StartBeforeID = PI->getTypeInfo();
103    } else {
104      if (!StartAfter.empty()) {
105        const PassInfo *PI = PR->getPassInfo(StartAfter);
106        if (!PI) {
107          errs() << "start-after pass is not registered.\n";
108          return 1;
109        }
110        StartAfterID = PI->getTypeInfo();
111      }
112      if (!StopAfter.empty()) {
113        const PassInfo *PI = PR->getPassInfo(StopAfter);
114        if (!PI) {
115          errs() << "stop-after pass is not registered.\n";
116          return 1;
117        }
118        StopAfterID = PI->getTypeInfo();
119      }
120    }
121
122    // Ask the target to add backend passes as necessary.
123    if (Target->addPassesToEmitFile(PM, *OS, FileType, false, StartBeforeID,
124                                    StartAfterID, StopAfterID, MIR.get())) {
125      errs() << " target does not support generation of this file type!\n";
126      return 1;
127    }
128
129    PM.run(*M);
130  }
131  // Declare success.
132  Out->keep();
133
134  return 0;
135}
136
137#endif
Note: See TracBrowser for help on using the repository browser.