2 #ifndef HOBBES_UTIL_LLVM_HPP_INCLUDED 3 #define HOBBES_UTIL_LLVM_HPP_INCLUDED 7 #include <llvm/Config/llvm-config.h> 9 #if LLVM_VERSION_MAJOR != 3 10 #error "I don't know how to use this version of LLVM" 13 #include <llvm/IR/DerivedTypes.h> 14 #include <llvm/IR/IRBuilder.h> 15 #include <llvm/IR/LLVMContext.h> 16 #include <llvm/IR/Module.h> 17 #include <llvm/IR/DataLayout.h> 18 #include <llvm/IR/InstIterator.h> 19 #include <llvm/Analysis/Passes.h> 20 #include <llvm/Transforms/Scalar.h> 21 #include <llvm/Transforms/Vectorize.h> 22 #include <llvm/Transforms/IPO.h> 23 #include <llvm/Transforms/Utils/Cloning.h> 24 #include <llvm/Support/TargetSelect.h> 25 #include <llvm/Support/TargetRegistry.h> 26 #include <llvm/Support/Signals.h> 27 #include <llvm/Bitcode/ReaderWriter.h> 28 #include <llvm/Support/raw_os_ostream.h> 29 #include <llvm/ExecutionEngine/ExecutionEngine.h> 30 #include <llvm/ExecutionEngine/JITEventListener.h> 31 #include <llvm/ExecutionEngine/SectionMemoryManager.h> 33 #if LLVM_VERSION_MINOR == 3 34 #include <llvm/Analysis/Verifier.h> 35 #include <llvm/PassManager.h> 36 #elif LLVM_VERSION_MINOR >= 5 37 #include <llvm/IR/Verifier.h> 38 #include <llvm/ExecutionEngine/SectionMemoryManager.h> 39 #include <llvm/IR/LegacyPassManager.h> 40 #include <llvm/Object/ELFObjectFile.h> 50 return llvm::getGlobalContext();
53 typedef std::vector<llvm::Type*>
Types;
55 typedef std::vector<llvm::Value*>
Values;
59 return llvm::Type::getVoidTy(
context());
63 return llvm::Type::getInt1Ty(
context());
67 return llvm::Type::getInt8Ty(
context());
75 return llvm::Type::getInt16Ty(
context());
79 return llvm::Type::getInt32Ty(
context());
83 return llvm::Type::getInt64Ty(
context());
87 return llvm::Type::getFloatTy(
context());
91 return llvm::Type::getDoubleTy(
context());
94 inline llvm::PointerType*
ptrType(llvm::Type* ty) {
95 return llvm::PointerType::getUnqual(ty);
98 inline llvm::ArrayType*
arrayType(llvm::Type* ty,
size_t sz) {
116 inline llvm::StructType*
recordType(llvm::Type* t0, llvm::Type* t1) {
120 inline llvm::StructType*
recordType(llvm::Type* t0, llvm::Type* t1, llvm::Type* t2) {
124 inline llvm::StructType*
recordType(llvm::Type* t0, llvm::Type* t1, llvm::Type* t2, llvm::Type* t3) {
128 inline llvm::StructType*
recordType(llvm::Type* t0, llvm::Type* t1, llvm::Type* t2, llvm::Type* t3, llvm::Type* t4) {
132 inline llvm::StructType*
recordType(llvm::Type* t0, llvm::Type* t1, llvm::Type* t2, llvm::Type* t3, llvm::Type* t4, llvm::Type* t5) {
136 inline llvm::StructType*
recordType(llvm::Type* t0, llvm::Type* t1, llvm::Type* t2, llvm::Type* t3, llvm::Type* t4, llvm::Type* t5, llvm::Type* t6) {
140 inline llvm::FunctionType*
functionType(
const Types& argTys, llvm::Type* rty) {
144 inline llvm::StructType*
varArrayType(llvm::Type* elemty,
size_t sz = 1) {
149 inline llvm::Value*
cast(llvm::IRBuilder<>* b, llvm::Type* ty, llvm::Value* v) {
150 return b->CreateBitCast(v, ty);
153 inline llvm::Constant*
ccast(llvm::Type* ty, llvm::Constant* v) {
154 return llvm::ConstantExpr::getBitCast(v, ty);
159 return llvm::Constant::getIntegerValue(
boolType(), llvm::APInt(1, x ? 1 : 0,
false));
163 return llvm::Constant::getIntegerValue(
charType(), llvm::APInt(8, x,
true));
166 inline llvm::Constant*
cvalue(
unsigned char x) {
167 return llvm::Constant::getIntegerValue(
charType(), llvm::APInt(8, x,
false));
171 return llvm::Constant::getIntegerValue(
shortType(), llvm::APInt(16, x,
false));
175 return llvm::Constant::getIntegerValue(
intType(), llvm::APInt(32, x,
true));
178 inline llvm::Constant*
cvalue(
unsigned int x) {
179 return llvm::Constant::getIntegerValue(
intType(), llvm::APInt(32, x,
true));
183 return llvm::Constant::getIntegerValue(
longType(), llvm::APInt(64, x,
true));
190 inline llvm::Constant*
cvalue(
double x) {
203 inline llvm::ConstantInt*
civalue(
unsigned char x) {
215 inline llvm::ConstantInt*
civalue(
unsigned int x) {
231 inline llvm::GlobalVariable*
prepgv(llvm::GlobalVariable* gv,
unsigned int align =
sizeof(
void*)) {
232 gv->setAlignment(
align);
238 inline llvm::Constant*
constant(llvm::Value* v,
bool globalPtrRefs) {
239 if (llvm::GlobalVariable* gv = llvm::dyn_cast<llvm::GlobalVariable>(v)) {
240 if (gv->isConstant()) {
244 return gv->getInitializer();
249 }
else if (llvm::Constant* c = llvm::dyn_cast<llvm::Constant>(v)) {
260 new llvm::GlobalVariable(
264 llvm::GlobalVariable::InternalLinkage,
273 for (Values::const_iterator v = vs.begin(); v != vs.end(); ++v) {
274 if (llvm::Constant* c =
constant(*v, globalPtrRefs)) {
291 inline llvm::Constant*
constArray(llvm::Module*
m,
const Constants& cs, llvm::Type* elemTy,
bool boxAsGlobalRefs =
false) {
292 llvm::ArrayType* aty =
arrayType(elemTy, cs.size());
293 llvm::StructType* saty =
varArrayType(elemTy, cs.size());
295 long arrayLen = cs.size();
296 Constants ncs = elemTy->isVoidTy() ?
Constants() : cs;
298 if (boxAsGlobalRefs) {
305 inline llvm::Value*
tryMkConstVarArray(llvm::IRBuilder<>* b, llvm::Module*
m, llvm::Type* elemTy,
const Values& vs,
bool globalPtrRefs) {
307 if (cs.size() != vs.size()) {
310 llvm::StructType* saty =
varArrayType(elemTy, cs.size());
315 new llvm::GlobalVariable(
319 llvm::GlobalVariable::InternalLinkage,
326 inline llvm::Constant*
padding(
unsigned int len) {
328 for (
unsigned int i = 0; i < len; ++i) {
329 pad.push_back(
cvalue((
unsigned char)0));
337 Record::Members::const_iterator
m = ms.begin();
338 while (m != ms.end()) {
339 if (m->field[0] ==
'.' && m->field[1] ==
'p') {
341 if (
FixedArray* fa = is<FixedArray>(m->type)) {
342 long asz = fa->requireLength();
343 plen = asz < 0 ? 0 : ((size_t)asz);
345 throw std::runtime_error(
"Cannot derive padding for pad field with non-padding type (internal error)");
357 inline Types
types(
const Constants& cs) {
359 for (
unsigned int c = 0; c < cs.size(); ++c) {
360 r.push_back(cs[c]->getType());
369 for (
size_t i = 0; i < rps.second.size(); ++i) {
370 if (llvm::Constant* c =
constant(rps.second[i], is<Array>(rty->
member(rps.first[i])))) {
383 for (
size_t i = 0; i < std::min<size_t>(cs.size(), tys.size()); ++i) {
384 if (is<Array>(tys[i])) {
399 if (crv.size() != rv.size()) {
406 new llvm::GlobalVariable(
410 llvm::GlobalVariable::InternalLinkage,
411 llvm::ConstantStruct::getAnon(pcs,
true)
419 inline llvm::Value*
offset(llvm::IRBuilder<>* b, llvm::Value* p, llvm::Value* o0) {
420 std::vector<llvm::Value*> idxs;
422 return b->CreateGEP(p, idxs);
425 inline llvm::Value*
offset(llvm::IRBuilder<>* b, llvm::Value* p,
int o0) {
429 inline llvm::Value*
offset(llvm::IRBuilder<>* b, llvm::Value* p,
int o0,
int o1) {
430 std::vector<llvm::Value*> idxs;
431 idxs.push_back(
cvalue(o0));
432 idxs.push_back(
cvalue(o1));
433 return b->CreateGEP(p, idxs);
436 inline llvm::Value*
offset(llvm::IRBuilder<>* b, llvm::Value* p,
int o0, llvm::Value* o1) {
437 std::vector<llvm::Value*> idxs;
438 idxs.push_back(
cvalue(o0));
440 return b->CreateGEP(p, idxs);
443 inline llvm::Value*
structOffset(llvm::IRBuilder<>* b, llvm::Value* p,
unsigned int fieldOffset) {
444 #if LLVM_VERSION_MINOR == 7 446 return b->CreateStructGEP(
nullptr, p, fieldOffset);
447 #elif LLVM_VERSION_MINOR >= 8 448 return b->CreateStructGEP(((llvm::PointerType*)p->getType())->getElementType(), p, fieldOffset);
450 return b->CreateStructGEP(p, fieldOffset);
454 #if LLVM_VERSION_MINOR >= 6 455 inline llvm::ExecutionEngine* makeExecutionEngine(llvm::Module*
m, llvm::SectionMemoryManager* smm) {
457 llvm::ExecutionEngine* ee =
458 llvm::EngineBuilder(std::unique_ptr<llvm::Module>(m))
460 .setMCJITMemoryManager(std::unique_ptr<llvm::SectionMemoryManager>(smm))
464 throw std::runtime_error(
"Internal error, failed to allocate execution engine with error: " + err);
468 #elif LLVM_VERSION_MINOR == 3 or LLVM_VERSION_MINOR == 5 469 inline llvm::ExecutionEngine* makeExecutionEngine(llvm::Module* m, llvm::SectionMemoryManager*) {
471 llvm::ExecutionEngine* ee =
472 llvm::EngineBuilder(m)
477 throw std::runtime_error(
"Internal error, failed to allocate execution engine with error: " + err);
483 inline llvm::Function*
externDecl(llvm::Function* remoteFn, llvm::Module* thisModule) {
484 if (llvm::Function* ef = thisModule->getFunction(remoteFn->getName())) {
487 return llvm::Function::Create(remoteFn->getFunctionType(), llvm::Function::ExternalLinkage, remoteFn->getName(), thisModule);
492 inline llvm::Function*
cloneFunction(llvm::Function *f, llvm::Module *targetMod) {
493 using namespace llvm;
494 if (f->isDeclaration())
500 auto iInst = llvm::inst_begin(f);
501 auto iInstEnd = llvm::inst_end(f);
503 if (++iInst == iInstEnd)
506 if (iInst != iInstEnd)
509 ValueToValueMapTy vmap;
510 SmallVector<ReturnInst*, 8> returns;
511 Function *newF = Function::Create(f->getFunctionType(), f->getLinkage(), f->getName(), targetMod);
512 Function::arg_iterator iDest = newF->arg_begin();
513 for (
const Argument &arg : f->args()) {
514 iDest->setName(arg.getName());
515 vmap[&arg] = &*iDest++;
518 CloneFunctionInto(newF, f, vmap,
false, returns);
522 inline llvm::Value*
fncall(llvm::IRBuilder<>* b, llvm::Value* vfn,
const Values& args) {
523 #if LLVM_VERSION_MINOR >= 6 524 llvm::Module* thisMod = b->GetInsertBlock()->getParent()->getParent();
526 llvm::Function*
fn = llvm::dyn_cast<llvm::Function>(vfn);
527 if (!fn || fn->getParent() == thisMod) {
529 return b->CreateCall(vfn, args);
533 return b->CreateCall(newF, args);
534 return b->CreateCall(
externDecl(fn, thisMod), args);
537 return b->CreateCall(vfn, args);
541 inline llvm::Value*
fncall(llvm::IRBuilder<>* b, llvm::Value*
fn, llvm::Value* arg) {
std::vector< llvm::Value * > Values
Definition: jitcc.H:216
llvm::Value * tryMkConstRecord(llvm::IRBuilder<> *, llvm::Module *m, const RecordValue &rv, const Record *rty)
Definition: llvm.H:397
Types types(const Constants &cs)
Definition: llvm.H:357
const size_t FUNCTION_SIZE_THRESHOLD
Definition: llvm.H:491
T align(T x, T m)
Definition: ptr.H:98
Constants liftArraysAsGlobals(llvm::Module *m, const Constants &cs, const MonoTypes &tys)
Definition: llvm.H:381
llvm::Type * voidType()
Definition: llvm.H:58
llvm::PointerType * ptrType(llvm::Type *ty)
Definition: llvm.H:94
llvm::Constant * padding(unsigned int len)
Definition: llvm.H:326
llvm::StructType * recordType(const Types &tys)
Definition: llvm.H:108
llvm::Value * cast(llvm::IRBuilder<> *b, llvm::Type *ty, llvm::Value *v)
Definition: llvm.H:149
llvm::GlobalVariable * prepgv(llvm::GlobalVariable *gv, unsigned int align=sizeof(void *))
Definition: llvm.H:231
llvm::Type * boolType()
Definition: llvm.H:62
Constants recordUZConstants(const UnzRecValues &rps, const Record *rty)
Definition: llvm.H:367
llvm::StructType * packedRecordType(const Types &tys)
Definition: llvm.H:104
llvm::Constant * liftAsGlobalRef(llvm::Module *m, llvm::Constant *c)
Definition: llvm.H:258
llvm::Value * offset(llvm::IRBuilder<> *b, llvm::Value *p, llvm::Value *o0)
Definition: llvm.H:419
std::pair< std::vector< L >, std::vector< R > > unzip(const std::vector< std::pair< L, R > > &ps)
Definition: array.H:238
llvm::LLVMContext & context()
Definition: llvm.H:49
Constants mergePadding(const Constants &cs, const Record::Members &ms)
Definition: llvm.H:334
llvm::Type * floatType()
Definition: llvm.H:86
llvm::Type * intType()
Definition: llvm.H:78
MonoType::ptr MonoTypePtr
Definition: type.H:71
llvm::StructType * varArrayType(llvm::Type *elemty, size_t sz=1)
Definition: llvm.H:144
llvm::FunctionType * functionType(const Types &argTys, llvm::Type *rty)
Definition: llvm.H:140
llvm::Type * byteType()
Definition: llvm.H:70
llvm::Type * shortType()
Definition: llvm.H:74
llvm::Type * doubleType()
Definition: llvm.H:90
T * get(variant< Ctors... > &v)
Definition: variant.H:156
llvm::Constant * ccast(llvm::Type *ty, llvm::Constant *v)
Definition: llvm.H:153
std::pair< std::string, llvm::Value * > FieldValue
Definition: llvm.H:224
llvm::ConstantInt * civalue(bool x)
Definition: llvm.H:195
std::vector< ConstFieldValue > ConstRecordValue
Definition: llvm.H:228
llvm::Value * tryMkConstVarArray(llvm::IRBuilder<> *b, llvm::Module *m, llvm::Type *elemTy, const Values &vs, bool globalPtrRefs)
Definition: llvm.H:305
const Members & alignedMembers() const
Definition: type.C:1361
std::pair< std::vector< std::string >, Values > UnzRecValues
Definition: llvm.H:365
llvm::Value * toLLVM(jitcc *, const ExprPtr &exp)
Definition: cexpr.C:617
llvm::Constant * cvalue(bool x)
Definition: llvm.H:158
llvm::Constant * constArray(llvm::Module *m, const Constants &cs, llvm::Type *elemTy, bool boxAsGlobalRefs=false)
Definition: llvm.H:291
std::vector< T > list()
Definition: array.H:25
size_t r(const reader::MetaData &md, size_t o, T *t)
Definition: storage.H:1730
ExprPtr fncall(const ExprPtr &f, const Exprs &args, const LexicalAnnotation &la)
Definition: expr.H:845
ExprPtr fn(const str::seq &vns, const ExprPtr &b, const LexicalAnnotation &la)
Definition: expr.H:837
std::vector< FieldValue > RecordValue
Definition: llvm.H:225
const MonoTypePtr & member(const std::string &mn) const
Definition: type.C:1316
std::pair< std::string, llvm::Constant * > ConstFieldValue
Definition: llvm.H:227
std::vector< Member > Members
Definition: type.H:435
llvm::Type * longType()
Definition: llvm.H:82
std::vector< MonoTypePtr > MonoTypes
Definition: type.H:72
llvm::ArrayType * arrayType(llvm::Type *ty, size_t sz)
Definition: llvm.H:98
llvm::Function * cloneFunction(llvm::Function *f, llvm::Module *targetMod)
Definition: llvm.H:492
llvm::Function * externDecl(llvm::Function *remoteFn, llvm::Module *thisModule)
Definition: llvm.H:483
llvm::Constant * constantRecord(llvm::Module *, const Constants &cs, const Record *rty)
Definition: llvm.H:393
Constants liftAsGlobalRefs(llvm::Module *m, const Constants &cs)
Definition: llvm.H:283
LexicalAnnotation m(const YYLTYPE &p)
Definition: hexpr.parse.C:127
std::vector< llvm::Type * > Types
Definition: llvm.H:53
std::string pad(size_t n)
Definition: str.C:50
std::vector< llvm::Constant * > Constants
Definition: llvm.H:54
llvm::Type * charType()
Definition: llvm.H:66
Constants varArrayConstants(const Values &vs, bool globalPtrRefs)
Definition: llvm.H:271
ExprPtr constant(bool x, const LexicalAnnotation &la)
Definition: expr.H:672
llvm::Value * structOffset(llvm::IRBuilder<> *b, llvm::Value *p, unsigned int fieldOffset)
Definition: llvm.H:443