首页 > 解决方案 > 当我在 llvm 中声明一个 int64 全局变量时出现问题

问题描述

我正在尝试使用llvm构建自己的 dsl。

在这里,我在使用 VS2017win32模式时遇到了一个奇怪的问题。我在一个模块中定义了一个int64全局变量,其值为 3 by external linkage

然后当我在另一个模块中声明这个变量并加载它的值时,我得到了 12884901891(与 0x300000003 相同)。当我在 Linux 上尝试这个时,它运行良好。

希望可以有人帮帮我。

Blow 是我的代码。CJITEngine 是一个简单的单例包。

PS。如果我用其他类型而不是 int64 来定义全局变量,例如 int32,float,double,这段代码可以运行良好。


    int main()
    {
        CJITEngine::Instance().Init();
        DataLayout &layout = CJITEngine::Instance().GetDataLayout();

        using fpType = void(*)(int64_t*);
        fpType fp = nullptr;

        string name("aaaaaaaa");

        {
            unique_ptr<Module> pModule = CJITEngine::Instance().CreateModule("module1");

            IRBuilder<>& m_oBuilder = CJITEngine::Instance().GetIRBuilder();
            Type* pType = m_oBuilder.getInt64Ty();
            GlobalVariable* pVarValue = new GlobalVariable(*pModule, pType, false, GlobalValue::ExternalLinkage,
                                                           m_oBuilder.getInt64(3), name);
            pVarValue->setAlignment(layout.getABITypeAlignment(pType));
            pVarValue->setDSOLocal(true);
            pModule->addModuleFlag(Module::Error, "NumRegisterParameters", m_oBuilder.getInt32(0));
            pModule->addModuleFlag(Module::Error, "wchar_size", m_oBuilder.getInt32(2));
            pModule->print(outs(), nullptr);
            std::cout << "--------------------------------------------------------" << std::endl;
            CJITEngine::Instance().AddModule(std::move(pModule));
        }

        /////////////////////////////////////////////////////////

        {
            unique_ptr<Module> pModule = CJITEngine::Instance().CreateModule("module2");

            LLVMContext& m_oContext = CJITEngine::Instance().GetContext();
            IRBuilder<>& m_oBuilder = CJITEngine::Instance().GetIRBuilder();
            Type* pType = m_oBuilder.getInt64Ty();
            GlobalVariable* pVarValue = new GlobalVariable(*pModule, pType, false, GlobalValue::ExternalLinkage,
                                                  nullptr, name);
            pVarValue->setAlignment(layout.getABITypeAlignment(pType));
            pVarValue->setDSOLocal(true);
            FunctionType* pFuncType = FunctionType::get(m_oBuilder.getVoidTy(), {Type::getInt64PtrTy(m_oContext)}, false);
            Function* pFunc = Function::Create(pFuncType, Function::ExternalLinkage, "func", pModule.get());

            pFunc->setDSOLocal(true);
            BasicBlock* pEntryBlock = BasicBlock::Create(m_oContext, "entry", pFunc);
            BasicBlock* pExitBlock = BasicBlock::Create(m_oContext, "exit");
            m_oBuilder.SetInsertPoint(pEntryBlock);

            auto agr = pFunc->args().begin();
            AllocaInst* pParam = m_oBuilder.CreateAlloca(agr->getType());
            pParam->setAlignment(layout.getABITypeAlignment(Type::getInt64PtrTy(m_oContext)));
            m_oBuilder.CreateAlignedStore(agr, pParam, layout.getABITypeAlignment(Type::getInt64PtrTy(m_oContext)));
            Value* pStr = m_oBuilder.CreateAlignedLoad(pVarValue, layout.getABITypeAlignment(Type::getInt64Ty(m_oContext)));
            Value* ppp= m_oBuilder.CreateAlignedLoad(pParam, layout.getABITypeAlignment(Type::getInt64PtrTy(m_oContext)));
            m_oBuilder.CreateAlignedStore(pStr, ppp, layout.getABITypeAlignment(Type::getInt64Ty(m_oContext)));

            m_oBuilder.CreateRetVoid();

            pModule->addModuleFlag(Module::Error, "NumRegisterParameters", m_oBuilder.getInt32(0));
            pModule->addModuleFlag(Module::Error, "wchar_size", m_oBuilder.getInt32(2));

            pModule->print(outs(), nullptr);
            CJITEngine::Instance().AddModule(std::move(pModule));

            JITSymbol symbol = CJITEngine::Instance().FindSymbol("func");
            fp = (fpType)static_cast<intptr_t>(cantFail(symbol.getAddress()));

            int64_t x = 10;
            fp(&x);
            std::cout << hex << x << endl; // x is 0x300000003 here
        }
        return 0;
    }

标签: llvmllvm-irllvm-c++-api

解决方案


推荐阅读