Variable-length Phi-node

All,

Is it possible to create something which has the same effect of a variable-length phi node in the C++ api. Specifically, create a phi-node where the number of incoming values is not known at the time of its creation.

If there is no such way of creating a phinode like that, would it be possible to create a dummy instruction and perform a replaceAllUsesWith? If so, what should the dummy instruction be?

Thanks,
Billy

Is it possible to create something which has the same effect of a variable-length phi node in the C++ api. Specifically, create a phi-node where the number of incoming values is not known at the time of its creation.

The PHI node preallocates its storage, so no.

If there is no such way of creating a phinode like that, would it be possible to create a dummy instruction and perform a replaceAllUsesWith? If so, what should the dummy instruction be?

You could use a PHI node with a small number if incoming blocks, and when you go past that number you could replace it with another one. Ideally though, you'd defer creating the block with the PHI node in it until you knew what the CFG would look like. What are you doing that means that you don't know how many incoming blocks a block has when you create it?

David

You can call addIncoming().

/// addIncoming - Add an incoming value to the end of the PHI list
///
void addIncoming(Value *V, BasicBlock *BB) {
assert(V && “PHI node got a null value!”);
assert(BB && “PHI node got a null basic block!”);
assert(getType() == V->getType() &&
“All operands to PHI node must be the same type as the PHI node!”);
if (NumOperands == ReservedSpace)
growOperands(); // Get more space!
// Initialize some new operands.
++NumOperands;
setIncomingValue(NumOperands - 1, V);
setIncomingBlock(NumOperands - 1, BB);
}

-Filip

Excellent.

What are you doing that means that you don’t know how many incoming blocks a block has when you create it?
I’m making a higher-level abstraction on top of allocated memory or “LazyVariable” – the goal is be able to create a variable (whose value can be get or set, and whose location (e.g. a pointer to the memory) can be found) which can use cached values instead of having to do many load/stores.

This is being implemented by a struct containing the pointer to the allocated memory, and map from BasicBlocks to the most recent cached Value (NULL if it is unknown / changed by an external process such as passing the pointer itself to a function). Since I always write instructions to BasicBlocks sequentially, this method is very efficient for removing unnecessary code without an additional pass. The reason I need the PHINode is to be able to combine cached values from previous blocks in a new cached value for the current node. However, as this only deals with LLVM code and not upper-level knowledge of how the variable is used, the “LazyVariable” won’t know how many predecessors a block will have.

Additionally, (for the finalization of the “LazyVariable”) is there a fast way to retrieve all of the predecessors to a BasicBlock in a function. Specifically, is there a fast way to iterate through all BasicBlocks which can break to a specific BasicBlock?