我使用llvm工具构建了一个简单的编译器,但是语句passManager.add(new llvm::DataLayout(*engine->getDataLayout()));不能很好地工作。

我在ubuntu16.04中测试了它,我的gcc版本是5.4.0

有人可以告诉我如何解决吗?非常感谢你!

//
// 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)

最佳答案

http://llvm.org/docs/doxygen/classllvm_1_1ExecutionEngine.html#a33b5c0a123a81645b5e3a307bb644b8c

llvm :: ExecutionEngine返回const DataLayout&(不是指针)。这应该可以解决您的问题-

passManager.add(new llvm::DataLayout(engine->getDataLayout()));

关于c++ - 错误:与“operator *”不匹配(操作数类型为“const llvm::DataLayout”),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55685266/

10-11 18:13