Writing an address space re-numbering pass?


I'm trying to figure how to write a Module pass that globally
renumbers address space numbers e.g.

From -> To

0 -> 1
1 -> 3
2 -> 2
3 -> 4
4 -> 999

I see that the address space number is a property that belongs to
Types[1] and that types are immutable, so I'm not sure how to
correctly implement this. But if it is I'd greatly appreciate advise
on how to do this.

- What do I need to iterate over? I couldn't see an obvious way to
iterate over Types belonging to a module, so do I just need to iterate
over "everything" (i.e. Functions, globals, aliases and instructions)
and somehow iterate over the types that they use? Doing it in the way
I just described (if it's even possible) sounds like a disaster
because types are uniqued so I would likely visit the same type
multiple times and might accidently change the types address space
again. I could use a SmallPtrSet to make sure I don't visit a type
more than once but the fact I would need to do this hints to me that
this is probably the wrong approach.

- How can I change the address space number associated with a Type?
Looking at the implementation it seems that ``getAddressSpace()`` just
returns ``getSubclassData()`` and it also looks like I can use
``setSubClassData()`` to set this. What is "Subclass" data for? If I
try to set the address space number this way it seems like a
**massive** hack which is already broken if Subclass data is used for
other things inside LLVM.

Just in case someone asks, I can't change the frontend that produces
the Module so I need a way of changing the address space numbers in a
pre-existing LLVM module.

[1] http://llvm.org/docs/doxygen/html/classllvm_1_1Type.html


This will cause problems for you, because LLVM currently enforces an invariant that allocas must be in AS 0.


Thanks David. That's good to know. I don't ever intend to change types
that are already in address space 0 so that was a bad example to give,

I don't suppose you have any insight on doing what I asked in the original post?


Hmm looking through the LLVM source some more I bumped into TypeFinder
which got me excited and then on closer inspection it only finds
Struct Types :(. I believe that the following types in a module can
have a non-zero address space (please correct me if I'm wrong).

- llvm::PointerTy
- llvm::ArrayTy
- llvm::VectorTy

Should I just make my own copy of TypeFinder and modify it to look for
these types or is there already existing functionality in LLVM that
does what I'm looking for?


I believe the correct way to do this would be to use ValueMapTypeRemapper to help you rewrite a function with the same instructions, but new types

I believe the correct way to do this would be to use ValueMapTypeRemapper to
help you rewrite a function with the same instructions, but new types

Thanks. I wasn't aware of this class. Was there a particular function
you had in mind that I could use this class with?
I took a look at the utilities that can use this class and I don't
fully understand them

All these functions use a ValueToValueMapTy (VMap). It looks quite
important but I'm not sure how the map is supposed to be used. Is the
map supposed to be empty and filled in by the function so that the
clients know how Values were mapped by the function or is the client
supposed to fill in the map first?

void llvm::CloneFunctionInto(...)

Looking at the implementation it seems the VMap should already contain
a mapping for function arguments, but this doesn't look like it will
copy function arguments and consequently ValueMapTypeRemapper won't be
called on function arguments, it only does this on instructions but I
may need to modify the type of the function as well. I suppose I could
do that bit myself (taking inspiration from llvm::CloneModule()).

Value * llvm::MapValue(...)

Looking at the implementation this won't call the ValueMapTypeRemapper
on Globals so this isn't any use.

Really what I want is the ability to clone an entire module but use
the ValueMapTypeRemapper but this doesn't seem to be an option.