[llvm-dev] Kaleidoscope tutorial: comments, corrections and Windows support

Mehdi Amini via llvm-dev llvm-dev at lists.llvm.org
Mon Feb 6 23:02:36 PST 2017


> On Feb 6, 2017, at 5:07 PM, Moritz Kroll via llvm-dev <llvm-dev at lists.llvm.org> wrote:
> 
> Hi,
> 
> I'm currently working my way through the tutorial with LLVM 3.9.1 on Windows (finished chapter 4) and stumbled over a few things which could be improved:

Any chance you would submit a patch to fix all this?

http://llvm.org/docs/DeveloperPolicy.html
http://llvm.org/docs/Phabricator.html

Thanks,

— 
Mehdi


> 
> - "LLVMContext" does not exist as a variable -> "TheContext"
>   - Chapter 3: 5 times
>   - Chapter 4: 1 time
>   - Chapter 5: 4 times
>   - Chapter 6: 2 times
>   - Chapter 7: 2 times
> 
> 3.4. Function Code Generation
> 
> - Wouldn't it make sense to have a
>   "Type *DoubleTy = Type::getDoubleTy(TheContext);"?
> - "Function *TheFunction = TheModule->getFunction(Proto->getName());"
>   The new getName method is unexpected, the tutorial user has to lookup
>   and copy the definition from the full listing.
> 
> 3.5. Driver Changes and Closing Thoughts
> 
> - "When you quit the current demo"
>   -> "When you quit the current demo (by sending an EOF
>   via CTRL+D on Linux or CTRL+Z and ENTER on Windows)"
>   (Windows users normally don't send EOF characters so they
>   usually don't know this shortcut)
> 
> 4.3. LLVM Optimization Passes
> 
> - Code for InitializeModuleAndPassManager:
>   - Remove "Context LLVMContext;"
>   - "TheJIT" comes out of nowhere and thus is not defined in the code
>     of the tutorial user. Setting the data layout could be added in
>     4.4, as it is at least not required for showing the improved body
>     of "test"
>   - "createBasicAliasAnalysisPass" does not exist anymore (llvm-3.9.1).
>     Also requires adaption of the text
> 
> 4.4. Adding a JIT Compiler
> 
> - Code for main:
>   - "TheJIT = llvm::make_unique<KaleidoscopeJIT>();" will cause a crash
>     due to an invalid read in "Datalayout::operator=" as
>     "EngineBuilder().selectTarget()" returns a nullptr when
>     "InitializeNativeTarget" has not been called yet.
>     Other problems occur if the other InitializeNative* functions are
>     not called. So you should add them here.
>   - The (silently added) "TheModule->print" call from chapter 3
>     is missing
> 
> - "The KaleidoscopeJIT class is a simple JIT built specifically for
>    these tutorials.":
>   It would be nice to mention, where to find the include file:
>   llvm-src/examples/Kaleidoscope/include/KaleidoscopeJIT.h
> 
> - "auto ExprSymbol = TheJIT->findSymbol("__anon_expr");":
>   On Windows, this will always fail as this function will search for
>   "ExportedSymbolsOnly" and the exported flag seems to be implemented
>   incorrectly for COFF in LLVM (see bug report from Russell Wallace:
>   http://lists.llvm.org/pipermail/llvm-dev/2016-April/097964.html ).
>   Applied to the current version of Kaleidoscope, he suggested to use
>   "CompileLayer.findSymbolIn(H, Name, false)" in
>   "KaleidoscopeJIT::findMangledSymbol" to also allow non-exported
>   symbols.
>   I fixed it by changing "COFFObjectFile::getSymbolFlags" in
>   llvm-src/lib/Object/COFFObjectFile.cpp
>   to additionally OR SymbolRef::SF_Exported to Result:
> 
>> uint32_t COFFObjectFile::getSymbolFlags(DataRefImpl Ref) const {
>>  COFFSymbolRef Symb = getCOFFSymbol(Ref);
>>  uint32_t Result = SymbolRef::SF_None;
>> 
>>  if (Symb.isExternal() || Symb.isWeakExternal())
>>    Result |= SymbolRef::SF_Global | SymbolRef::SF_Exported;
> 
>   Works and sounds reasonable to me, but maybe you can prove me wrong.
> 
> - "ready> sin(1.0);": On Windows, this fails with "LLVM ERROR: Program
>   used external function '_sin' which could not be resolved!" because
>   "DynamicLibrary::SearchForAddressOfSymbol" iterates over all loaded
>   libraries and uses GetProcAddress to try getting the address.
>   But for the old "msvcrt.dll" as well as the newer "ucrtbased.dll",
>   the math functions are exported without a leading underscore.
>   Additionally, LLVM provides some "explicit" symbols which would
>   otherwise only exist in form of a macro (see comment in
>   llvm-src/lib/Support/Windows/DynamicLibrary.inc). These are also only
>   available in unmangled form, for example "sinf".
>   Thus I propose to add this code at the end of
>   "KaleidoscopeJIT::findMangledSymbol":
> 
>> #ifdef LLVM_ON_WIN32
>>    // For Windows retry without "_" at begining, as RTDyldMemoryManager uses
>>    // GetProcAddress and standard libraries like msvcrt.dll use names
>>    // with and without "_" (for example "_itoa" but "sin").
>>    if (Name.length() > 2 && Name[0] == '_')
>>      if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(
>>            Name.substr(1)))
>>        return JITSymbol(SymAddr, JITSymbolFlags::Exported);
>> #endif
>> 
>>    return nullptr;
>>  }
> 
> - "ready> sin(1.0);
>    Read top-level expression:
>    define double @2() {
>    entry:
>      ret double 0x3FEAED548F090CEE
>    }
> 
>    Evaluated to 0.841471":
>   Actually "sin" is not called at all, LLVM knew "sin" and just returns
>   the already const-folded value.
>   In my case, I do see a
>   "%calltmp = call double @sin(double 1.000000e+00)",
>   though, inspite of the same optimizations as in your listing...
> 
> - "ready> def foo(x) sin(x)*sin(x) + cos(x)*cos(x);
>    Read function definition:
>    define double @foo(double %x) {
>    entry:
>      %calltmp = call double @sin(double %x)
>      %multmp = fmul double %calltmp, %calltmp
>      %calltmp2 = call double @cos(double %x)
>      %multmp4 = fmul double %calltmp2, %calltmp2
>      %addtmp = fadd double %multmp, %multmp4
>      ret double %addtmp
>    }":
>   In my case, the CSE does not work, although it does work for the
>   example in 4.3:
>    "ready> def foo(x) sin(x)*sin(x) + cos(x)*cos(x);
>    ready> Read function definition:
>    define double @foo(double %x) {
>    entry:
>      %calltmp = call double @sin(double %x)
>      %calltmp1 = call double @sin(double %x)
>      %multmp = fmul double %calltmp, %calltmp1
>      %calltmp2 = call double @cos(double %x)
>      %calltmp3 = call double @cos(double %x)
>      %multmp4 = fmul double %calltmp2, %calltmp3
>      %addtmp = fadd double %multmp, %multmp4
>      ret double %addtmp
>    }"
> 
> - "extern putchard(x); putchard(120);":
>   Again, on Windows, this doesn't work. To make it work, you have to
>   use "extern "C" __declspec(dllexport) double putchard(double X)"
>   so the function will be found via GetProcAddress for the main module.
>   This wouldn't hurt for Linux / Mac, would it?
> 
> Best regards
> Moritz Kroll
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev



More information about the llvm-dev mailing list