Я использую инструменты llvm для создания простого компилятора, но оператор passManager.add(new llvm::DataLayout(*engine->getDataLayout()));
работает не очень хорошо.
Я тестирую его в ubuntu16.04, и моя версия gcc - 5.4.0
* 1005.* Может кто-нибудь сказать мне, как это исправить?Большое спасибо!
//
// Created by tuhaoxin on 2019-04-14.
//
#include <llvm/IR/Function.h>
#include "llvm/ADT/APInt.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Analysis/Passes.h" // this
#include "llvm/IR/LegacyPassManager.h" // this
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/IR/DataLayout.h" // this
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h" // this
#include "llvm/IR/Dominators.h"
#include "Expr.h"
#include "Lexer.h"
#include "Parser.h"
llvm::Function *createEntryFunction(
llvm::Module *module,
llvm::LLVMContext &context) {
llvm::Function *function =
llvm::cast<llvm::Function>(
module->getOrInsertFunction("fun",
llvm::Type::getInt32Ty(context),
llvm::Type::getInt32Ty(context),
(llvm::Type *)0)
);
llvm::BasicBlock *bb = llvm::BasicBlock::Create(context, "entry", function);
llvm::IRBuilder<> builder(context);
builder.SetInsertPoint(bb);
llvm::Argument *argX = function->arg_begin();
argX->setName("x");
VarExpr::varValue = argX;
Lexer lexer;
Parser parser(&lexer);
Expr* expr = parser.parseExpr();
llvm::Value* retVal = expr->gen(&builder, context);
builder.CreateRet(retVal);
return function;
}
llvm::ExecutionEngine* createEngine(llvm::Module *module) {
llvm::InitializeNativeTarget();
std::string errStr;
llvm::ExecutionEngine *engine =
llvm::EngineBuilder(std::unique_ptr<llvm::Module> (module))
.setErrorStr(&errStr)
.setEngineKind(llvm::EngineKind::JIT)
.create();
if (!engine) {
llvm::errs() << "Failed to construct ExecutionEngine: " << errStr << "\n";
} else if (llvm::verifyModule(*module)) {
llvm::errs() << "Error constructing function!\n";
}
return engine;
}
void JIT(llvm::ExecutionEngine* engine, llvm::Function* function, int arg) {
std::vector<llvm::GenericValue> Args(1);
Args[0].IntVal = llvm::APInt(32, arg);
llvm::GenericValue retVal = engine->runFunction(function, Args);
llvm::outs() << "Result: " << retVal.IntVal << "\n";
}
void optimizeFunction(
llvm::ExecutionEngine* engine,
llvm::Module *module,
llvm::Function* function
) {
llvm::legacy::FunctionPassManager passManager(module);
passManager.add(new llvm::DataLayout(*engine->getDataLayout()));
passManager.add(llvm::createLoopInstSimplifyPass());
passManager.add(llvm::createReassociatePass());
passManager.add(llvm::createNewGVNPass());
passManager.add(llvm::createCFGSimplificationPass());
passManager.doInitialization();
passManager.run(*function);
}
int main(int argc, char** argv) {
if (argc != 2) {
llvm::errs() << "Inform an argument to your expression.\n";
return 1;
} else {
llvm::LLVMContext context;
llvm::Module *module = new llvm::Module("Example", context);
llvm::Function *function = createEntryFunction(module, context);
llvm::errs() << "Module before optimizations:\n";
module->dump();
llvm::errs() << "Module after optimizations:\n";
llvm::ExecutionEngine* engine = createEngine(module);
optimizeFunction(engine, module, function);
module->dump();
JIT(engine, function, atoi(argv[1]));
}
}
ошибки:
In function ‘void optimizeFunction(llvm::ExecutionEngine*, llvm::Module*, llvm::Function*)’:
/home/haoxin/github/dcc888/dcc888-1/Driver.cpp:79:42: error: no match for ‘operator*’ (operand type is ‘const llvm::DataLayout’)
passManager.add(new llvm::DataLayout(*engine->getDataLayout()));
^
In file included from /usr/lib/llvm-6.0/include/llvm/ADT/APFloat.h:20:0,
from /usr/lib/llvm-6.0/include/llvm/IR/Type.h:18,
from /usr/lib/llvm-6.0/include/llvm/IR/DerivedTypes.h:24,
from /usr/lib/llvm-6.0/include/llvm/IR/Function.h:30,
from /home/haoxin/github/dcc888/dcc888-1/Driver.cpp:4:
/usr/lib/llvm-6.0/include/llvm/ADT/APInt.h:2075:14: note: candidate: llvm::APInt llvm::operator*(uint64_t, llvm::APInt)
inline APInt operator*(uint64_t LHS, APInt b) {
^
/usr/lib/llvm-6.0/include/llvm/ADT/APInt.h:2075:14: note: candidate expects 2 arguments, 1 provided
/usr/lib/llvm-6.0/include/llvm/ADT/APInt.h:2070:14: note: candidate: llvm::APInt llvm::operator*(llvm::APInt, uint64_t)
inline APInt operator*(APInt a, uint64_t RHS)