How To Upgrade LLVM

Last Author
Last Updated
1238 Days Ago

This is a rough guide on upgrading the version of LLVM into which LegUp is built.

Get New LLVM

Download LLVM source
I recommend using the source from a major release, not from the svn repo. There are two main reasons for this:

  1. The release should be more stable
  2. In the future, it will be easier to diff against a major release rather than having to figure out which revision was used, and getting that revision.


Use git.
This makes it easier for others, in the future, to understand (and reproduce) the changes you make.
I would recommend making one initial git commit when you put the new llvm in the legup/llvm directory, then another commit for each set of changes you make to LLVM, the Verilog backend, the LegUp transforms, or the build system.

WARNING: git may ignore some files (*.inc, etc) due to .gitignore rules in legup/ and legup/llvm. You may want to disable gitignore temporarily.

You may also want to look at the git history for examples that show what changes were made for previous LLVM updates.

NOTE: It may also be possible to do a 3-way git merge and avoid much of the rest of the grunt work that follows.

Next Steps

Copy New LLVM

  • Copy legup/llvm to legup/llvm-old or something
  • git remove legup/llvm
  • Copy the new llvm into legup/llvm
  • git add legup/llvm
  • git commit
  • cp legup/llvm-old/lib/Target/Verilog to legup/llvm/lib/Target
  • cp legup/llvm-old/lib/Transforms/LegUp to legup/llvm/lib/Transforms

Build-System Changes

  • edit legup/llvm/lib/Target/LLVMBuild.txt and add Verilog to the list of subdirectories
  • edit legup/llvm/lib/Transforms/CMakeLists.txt and add LegUp as a subdirectory
  • edit legup/llvm/lib/Transforms/LLVMBuild.txt and add LegUp as a subdirectory
  • edit legup/llvm/lib/Transforms/Makefile and add LegUp as a parallel directory
  • diff legup/llvm/ agains legup/llvm-old/ and copy any changes that pertain to:
    • tcl
    • lpsolve
  • diff legup/llvm/include/llvm/Config/ against the old version and add the line that pertains to tcl.
  • edit legup/llvm/CMakeLists.txt and add Verilog to the list LLVM_ALL_TARGETS
  • diff legup/llvm/autoconf/ against legup/llvm-old/autoconf/ and copy the changes that pertain to:
    • Verilog
    • tcl
    • lpsolve
    • mysql
  • run legup/llvm/autoconf/
    • you may need to edit to update the versions of autoconf and aclocal that it "requires":
      • want_autoconf_version=
      • want_aclocal_version=
      • to match your versions of autoconf and aclocal. (Run autoconf --version to get your version).

Changes to LLVM

  • diff legup/llvm/include/llvm/IR/Value.h against the old version and re-add Nazanin's changes (NC changes)
  • diff legup/llvm/lib/IR/AsmWriter.cpp against the old version and re-add Nazanin's changes (NC changes)
  • reapply changes in the following files:
    • legup/llvm/lib/Transforms/Scalar/SROA.cpp
    • legup/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
    • legup/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp
llc and opt Changes
  • diff legup/llvm/tools/llc/ agains legup/llvm-new/tools/llc/ and copy any changes in any files (especially Makefile and llc.cpp) that have anything to do with:
    • Verilog
    • tcl
    • LegUp
  • do the same thing for the legup/llvm/tools/opt directory
  • git add
  • git commit
Add indvars2 Pass

See this commit:

Lots of small changes to make here:

  • legup/llvm/include/llvm/InitializePass.h
  • legup/llvm/include/llvm/LinkAllPasses.h
  • legup/llvm/include/llvm/Transforms/Scalar.h
  • legup/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h

you should be able to diff agains the old version to find the minor changes you need to make.

Also changes here:

  • llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
  • llvm/lib/Transforms/Scalar/Scalar.cpp
  • llvm/lib/Transforms/Scalar/CMakeLists.txt

And copy this file from the old llvm:

  • llvm/lib/Transforms/Scalar/IndVarSimplify2.cpp


  • do a 'make clean' in legup/llvm
  • run 'make' from legup/ to make sure that LLVM gets configured properly (so it knows where cloog and isl are).
  • When you run make, the build will probably fail somewhere in lib/Target/Verilog or lib/Transforms/LegUp

Fixing Compile Errors

ambiguous overload for operator|, operator&, etc

This is caused by including uint128_t.h in lib/Target/Verilog. The easiest solution I've found is to add explicit casts on the lines that conflict (these lines are in files outside lib/Target/Verilog and lib/Transforms/LegUp). (just cast to (int) ).
You may see this in:

  • legup/llvm/include/llvm/Support/Dwarf.h
  • legup/llvm/include/llvm/Analysis/AliasAnalysis.h

Other Errors

Most of the other errors you will see are due to changes in the LLVM framework. Some functions take different numbers of arguments. Some functions have been renamed. Some functions have been moved to different classes. You will need to compare the old and new LLVM doxygen documentation to figure out what needs to be changed.

Hints and Tips

In some cases the functionality that was available in the old LLVM is changed or no longer available. Sometimes you may be able to solve a problem like this by looking at the documentation/source for the older version of LLVM, and copying parts of the implementation into the LegUp files. ie. sometimes the old llvm provides a wrapper function (sometimes with a little extra functionality), and that wrapper function has been removed in the new llvm. You can just copy that old wrapping/functionality into the LegUp file that needs it.

Fixing Runtime Errors

There are a lot of features of LegUp that will need to be verified:

  • pure HW
  • hybrid flow
  • parallel flow
  • loop pipelining
  • mips backend
  • arm backend

You may find runtime errors when running these flows.

The LLVM stack trace will give you a rough idea of where it failed.