0

This question is about an error thrown by KaleidoscopeJIT.h. I am currently following the LLVM tutorial here but adding some more classes and objects to the design. Since I am using an older version of LLVM, I am borrowing some of the code from the older version (v10.0.0) of the llvm-project repo.

Where the issue is

I am currently am on Chapter 4 and I am trying to get the JIT compilation to work for top-level expressions (specifically simple arithmetic like 4+5 => "Evaluated to 9.0"). I am using a LLVMIRGen class with a method generateIR(/*AST root*/). This is then evaluated as follows :

int LLVMIRGenerator::generateIR(const std::unique_ptr<NodeAST> &root) {
    
    if (FunctionAST *functionAST = dynamic_cast<FunctionAST *>(root.get())) {
        /** stuff for functions and top-level expressions */
        
    } else if (PrototypeAST *prototypeAST = dynamic_cast<PrototypeAST *>(root.get())) {
        /* stuff for prototypes */
    } else {
        /* error msg etc. */
    }

    return 0;
}

The error stems from the following piece of my code:

if (functionAST->getPrototype()->getName().find("__anon_expr") != std::string::npos) {
            std::unique_ptr<Module> copied = CloneModule(*TheModule.get());
            
            auto H = myJIT->addModule(std::move(copied)); // THIS IS WHERE THE ERROR OCCURS.

            // Search the JIT for the __anon_expr symbol.
            auto ExprSymbol = myJIT->findSymbol("__anon_expr"  + std::to_string(anon_counter++));
            assert(ExprSymbol && "Function not found");

            // Get the symbol's address and cast it to the right type (takes no
            // arguments, returns a double) so we can call it as a native function.
            double (*FP)() = (double (*)())(intptr_t)cantFail(ExprSymbol.getAddress());
            fprintf(stderr, "Evaluated to %f\n", FP());

            // Delete the anonymous expression module from the JIT.
            myJIT->removeModule(H);
        }

The above piece of code checks if the function is an "anonymous function" (i.e a top level expression) and if it is then it executes the expression. This piece of code is taken from the HandleTopLevelExpression() function in the linked llvm-project repository above.

However, when I type in 4+5 in the prompt the exact error is :


ready>4+5
LLVM ERROR: Cannot select: 0x70f290: f64 = add 0x70f5d0, 0x70f568
  0x70f5d0: f64,ch = load<(load 8 from constant-pool)> 0x6937a8, 0x70f638, undef:i64
    0x70f638: i64 = X86ISD::Wrapper TargetConstantPool:i64<double 4.000000e+00> 0
      0x70f1c0: i64 = TargetConstantPool<double 4.000000e+00> 0
    0x70f500: i64 = undef
  0x70f568: f64,ch = load<(load 8 from constant-pool)> 0x6937a8, 0x70f6a0, undef:i64
    0x70f6a0: i64 = X86ISD::Wrapper TargetConstantPool:i64<double 5.000000e+00> 0
      0x70f228: i64 = TargetConstantPool<double 5.000000e+00> 0
    0x70f500: i64 = undef
In function: __anon_expr0

I think I have correctly initialized the Kaleidoscope JIT in the constructor as :

LLVMIRGenerator() {
    InitializeNativeTarget();
    InitializeNativeTargetAsmPrinter();
    InitializeNativeTargetAsmParser();

    // Open a new context and module.
    myJIT = std::make_unique<orc::KaleidoscopeJIT>();

    TheContext = std::make_unique<LLVMContext>();
    TheModule = std::make_unique<Module>("KEANE'S JIT.C", *TheContext);
    TheModule->setDataLayout(myJIT->getTargetMachine().createDataLayout());

    ....
}

Why exactly am I getting this error ?

What have I done so far ?

I am following the code from the Kaleidoscope project closely.One thing I have changed however is that the module I have is for the entire AST and not just for a single expression like they have done in the code. Hence I do not have the InitializeModuleAndPassManager() line in my code.

I am not sure why I am getting this issue. So far I have tried moving the initialization of the JIT around to different places but to no avail.

My code is currently in the linked Github repo : verCE

Keane Moraes
  • 1
  • 1
  • 3

0 Answers0