This is similar to Inserting a block between two blocks in LLVM however the solution description is unclear to me - or better - I tried to do it like described but it does not work (for me).
What I want to do:
Wherever a basic block has more then one successor, I want to insert a basic block.
So if basic block A does a conditional jump to B or C, I want to insert a basic block between A and B and between A and C. And it should also work if there is a jump table.
So what I do is:
while (...) {
// get next basic block and ensure it has at least 2 successors:
BasicBlock *origBB = getNextBB();
Instruction *TI = origBB->getTerminator()
if (!TI || TI->getNumSuccessors() < 2)
continue;
// collect successors:
std::vector<BasicBlock *> Successors;
for (succ_iterator SI = succ_begin(origBB), SE = succ_end(origBB); SI != SE; ++SI) {
BasicBlock *succ = *SI;
Successors.push_back(succ);
}
// now for each successor:
for (uint32_t i = 0; i < Successors.size(); i++) {
// Create a new basic block
BasicBlock *BB = BasicBlock::Create(C, "", &F, nullptr);
// F.getBasicBlockList().push_back(BB); <= this did not work, seem to result in endless loop
IRBuilder<> IRB(BB);
// put instructions into BB
... // omitted
// then add the terminator:
IRB.CreateBr(Successors[i]);
// Now we have to fix the original BB to our new basic block:
TI->setSuccessor(i, BB);
}
}
When I run this LLVM pass I get the following error:
PHI node entries do not match predecessors!
OK so I thought I have to remove the corresponding predecessor from the successor and added the following code after the setSuccessor():
origBB->replaceSuccessorsPhiUsesWith(Successors[j], BB);
BasicBlock *S = Successors[i];
S->removePredecessor(origBB);
Then however I get the error Instruction does not dominate all uses!
I am sure the solution is very simple - but I cannot find it :-(
Thanks a lot for any help or pointers!
OK I am anwsering my own question here.
The comment proposing a) using splitBlock() is going into the wrong direction as it is about inserting into an edge so the result would be wrong. b) updating the phi would actually solve the issue. However this is very complex as a simple replacePhiUsesWith cannot be used - the case where A->B and A is a loop head and B a loob tail (so going back to B) will result in a compilation error, so all phis have to be carefully evaluated.
So the solution is actually very simple, which I found browsing through the source code of llvm: SplitEdge(). It does exactly what I want, inserting a a basic block between the edge of two basic blocks!
It is not obvious as the function is not documented in the doxygen class list, so other than by browsing sources and includes it cannot be found.
So here how to use it:
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
void inYourFunction() {
...
// Insert the new block into the edge between thisBB and a successorBB
BasicBlock *insertedBB = SplitEdge(thisBB, successorBB);
if (!insertedBB) {
// SplitEdge can fail, e.g. if the successor is a landing pad
return;
}
// Then put instructions into the new BB
BasicBlock::iterator IP = newBB->getFirstInsertionPt();
IRBuilder<> IRB(&(*IP));
// and then work with IRB
// You need not to take care of the branch to successorBB - it is already there
...
}
Thats it, its that simple.
Related
I have:
std::unordered_set<ObjectRepresentation*> incompletePieces;
I would like to get exactly one object from the unordered_set. To do that I am using a for loop, and "break", at the end of the loop so that the loop runs at most once.
while (incompletePieces.size()){
for (auto containedPiece : incompletePieces){ //Warning at this line that loop will run at most once
// .... doing some stuff with the contained piece
incompletePieces.erase(containedPiece);
break;
}
}
This is the desired behaviour that I want. The problem is that the compiler shows a warning:
Loop will run at most once (loop increment never executed)
How do I rewrite my code so that the warning goes away ? Is there a better way to get an item from the unordered_set ?
You could use begin() to get the first element.
if (incompletePieces.size() > 0)
auto containedPiece = *(incompletePieces.begin());
The code you presented does in fact process all elements and clears the set of them as it gets done, but it does so in a highly unidiomatic way.
There are two idiomatic ways of doing this, depending on whether processing an element could modify the set itself.
1) If the "doing some stuff" code is guaranteed to not touch incompletePieces (i.e. completing one piece does not create additional incomplete pieces), then the idiomatic and efficient solution is to just loop over the set and clear it afterwards:
for (auto piece : incompletePieces) {
// process piece
}
incompletePieces.clear();
2) If this is not the case, or you really need to clear elements as you go, then the idiomatic solution is still iterator based looping:
auto it = incompletePieces.begin();
while (it != incompletePieces.end()) {
// process *it
#if C++11
it = incompletePieces.erase(it);
#else
auto prev = it++;
incompletePieces.erase(prev);
#endif
}
Whereas *unordered_set::begin() will give you first element (no unordered_set::front()),
I would rewrite:
while (incompletePieces.size()){
for (auto containedPiece : incompletePieces){
// .... doing some stuff with the contained piece
incompletePieces.erase(containedPiece);
break;
}
}
into:
for (auto* containedPiece : incompletePieces){
// .... doing some stuff with the contained piece
}
incompletePieces.clear();
You can rewrite the code as below:
for(auto* containedPiece : incompletePieces){
//Process the set contents
}
//Clear entire set in one go
incompletePieces.clear();
If you want to clear it one by one, you would have to use iterators as shown below:
auto it = incompletePieces.begin(); //Take the pointer to first element of set
for( ; it !=incompletePieces.end() ; it++){
incompletePieces.erase(*it); //Erase one element at a time
}
I have a global unique path table which can be thought of as a directed un-weighted graph. Each node represents either a piece of physical hardware which is being controlled, or a unique location in the system. The table contains the following for each node:
A unique path ID (int)
Type of component (char - 'A' or 'L')
String which contains a comma separated list of path ID's which that node is connected to (char[])
I need to create a function which given a starting and ending node, finds the shortest path between the two nodes. Normally this is a pretty simple problem, but here is the issue I am having. I have a very limited amount of memory/resources, so I cannot use any dynamic memory allocation (ie a queue/linked list). It would also be nice if it wasn't recursive (but it wouldn't be too big of an issue if it was as the table/graph itself if really small. Currently it has 26 nodes, 8 of which will never be hit. At worst case there would be about 40 nodes total).
I started putting something together, but it doesn't always find the shortest path. The pseudo code is below:
bool shortestPath(int start, int end)
if start == end
if pathTable[start].nodeType == 'A'
Turn on part
end if
return true
else
mark the current node
bool val
for each node in connectedNodes
if node is not marked
val = shortestPath(node.PathID, end)
end if
end for
if val == true
if pathTable[start].nodeType == 'A'
turn on part
end if
return true
end if
end if
return false
end function
Anyone have any ideas how to either fix this code, or know something else that I could use to make it work?
----------------- EDIT -----------------
Taking Aasmund's advice, I looked into implementing a Breadth First Search. Below I have some c# code which I quickly threw together using some pseudo code I found online.
pseudo code found online:
Input: A graph G and a root v of G
procedure BFS(G,v):
create a queue Q
enqueue v onto Q
mark v
while Q is not empty:
t ← Q.dequeue()
if t is what we are looking for:
return t
for all edges e in G.adjacentEdges(t) do
u ← G.adjacentVertex(t,e)
if u is not marked:
mark u
enqueue u onto Q
return none
C# code which I wrote using this code:
public static bool newCheckPath(int source, int dest)
{
Queue<PathRecord> Q = new Queue<PathRecord>();
Q.Enqueue(pathTable[source]);
pathTable[source].markVisited();
while (Q.Count != 0)
{
PathRecord t = Q.Dequeue();
if (t.pathID == pathTable[dest].pathID)
{
return true;
}
else
{
string connectedPaths = pathTable[t.pathID].connectedPathID;
for (int x = 0; x < connectedPaths.Length && connectedPaths != "00"; x = x + 3)
{
int nextNode = Convert.ToInt32(connectedPaths.Substring(x, 2));
PathRecord u = pathTable[nextNode];
if (!u.wasVisited())
{
u.markVisited();
Q.Enqueue(u);
}
}
}
}
return false;
}
This code runs just fine, however, it only tells me if a path exists. That doesn't really work for me. Ideally what I would like to do is in the block "if (t.pathID == pathTable[dest].pathID)" I would like to have either a list or a way to see what nodes I had to pass through to get from the source and destination, such that I can process those nodes there, rather than returning a list to process elsewhere. Any ideas on how i could make that change?
The most effective solution, if you're willing to use static memory allocation (or automatic, as I seem to recall that the C++ term is), is to declare a fixed-size int array (of size 41, if you're absolutely certain that the number of nodes will never exceed 40). By using two indices to indicate the start and end of the queue, you can use this array as a ring buffer, which can act as the queue in a breadth-first search.
Alternatively: Since the number of nodes is so small, Bellman-Ford may be fast enough. The algorithm is simple to implement, does not use recursion, and the required extra memory is only a distance (int, or even byte in your case) and a predecessor id (int) per node. The running time is O(VE), alternatively O(V^3), where V is the number of nodes and E is the number of edges.
I've been searching for hours and I can't find anything that could help me. I'm working on a project that involves a FunctionPass. I've implemented a runOnFunction(Function &f) method and that's working fine. Basically it needs to:
1) Detect a store instruction
2) Convert the memory address of the store instruction to an Integer
3) Alter the integer using a bitwise AND operation (0000FFFF)
4) Convert the integer back into the pointer
So far I've got the following:
virtual bool runOnFunction(Function &F) {
for (Function::iterator bb = F.begin(), bbe = F.end(); bb != bbe; ++bb) {
BasicBlock& b = *bb;
for (BasicBlock::iterator i = b.begin(), ie = b.end(); i != ie; ++i) {
if(StoreInst *si = dyn_cast<StoreInst>(&*i)) {
PtrToIntInst* ptrToInt = new PtrToIntInst(si->getPointerOperand(), IntegerType::get(si->getContext(), 32), "", si);
}
}
}
return true;
}
I can't for the life of me figure out how to actually insert the instruction, or even find a way to create an AND instruction. If anyone could point me in the right direction, that would be great.
Thanks in advance.
I recommend taking a look at the Programmer's Manual - it has a pretty decent coverage of the basics.
In particular, there's a section about creating and inserting new instructions. The simplest way is just to provide an existing instruction as the last argument for the new instruction's constructor, which will then insert that instruction immediately before the existing one.
Alternatively, you can pass the enclosing basic block if you just want to add to its end (but remember you need to take care of the terminator!). Finally, you can just call getInstList() on the enclosing basic block, then insert or push_back to insert new instructions there.
As an aside, you don't have to iterate over all blocks and then over all instructions in each, you can just iterate over the instructions directly; see the section about the instruction iterator in the programmer's manual.
virtual bool runOnFunction(Function &F) {
for (Function::iterator bb = F.begin(), bbe = F.end(); bb != bbe; ++bb) {
BasicBlock &b = *bb;
for (BasicBlock::iterator i = b.begin(), ie = b.end(); i != ie; ++i) {
if (StoreInst *si = dyn_cast<StoreInst>(&*i)) {
IRBuilder Builder(si);
Value *StoreAddr = Builder.CreatePtrToInt(si->getPointerOperand(), Builder.getInt32Ty());
Value *Masked = Builder.CreateAnd(StoreAddr, 0xffff);
Value *AlignedAddr = Builder.CreateIntToPtr(Masked, si->getPointerOperand()->getType());
// ...
}
}
}
return true;
}
You can use an IRBuilder to easily insert new instructions before another instruction or at the end of a basic block.
Alternatively, if you need to insert an instruction after another one, you need to use the instruction list in the containing basic block:
BasicBlock *pb = ...;
Instruction *pi = ...;
Instruction *newInst = new Instruction(...);
pb->getInstList().insertAfter(pi, newInst);
Code and solution taken from here.
Okay, I have been set with the task of comparing this list of Photons using one method (IU) and comparing it with another (TSP). I need to take the first IU photon and compare distances with all of the TSP photons, find the smallest distance, and "pair" them (i.e. set them both in arrays with the same index). Then, I need to take the next photon in the IU list, and compare it to all of the TSP photons, minus the one that was chosen already.
I know I need to use a Boolean array of sorts, with keeping a counter. I can't seem to logic it out entirely.
The code below is NOT standard C++ syntax, as it is written to interact with ROOT (CERN data analysis software).
If you have any questions with the syntax to better understand the code, please ask. I'll happily answer.
I have the arrays and variables declared already. The types that you see are called EEmcParticleCandidate and that's a type that reads from a tree of information, and I have a whole set of classes and headers that tell that how to behave.
Thanks.
Bool_t used[2];
if (num[0]==2 && num[1]==2) {
TIter photonIterIU(mPhotonArray[0]);
while(IU_photon=(EEmcParticleCandidate_t*)photonIterIU.Next()){
if (IU_photon->E > thresh2) {
distMin=1000.0;
index = 0;
IU_PhotonArray[index] = IU_photon;
TIter photonIterTSP(mPhotonArray[1]);
while(TSP_photon=(EEmcParticleCandidate_t*)photonIterTSP.Next()) {
if (TSP_photon->E > thresh2) {
Float_t Xpos_IU = IU_photon->position.fX;
Float_t Ypos_IU = IU_photon->position.fY;
Float_t Xpos_TSP = TSP_photon->position.fX;
Float_t Ypos_TSP = TSP_photon->position.fY;
distance_1 = find distance //formula didnt fit here //
if (distance_1 < distMin){
distMin = distance_1;;
for (Int_t i=0;i<2;i++){
used[i] = false;
} //for
used[index] = true;
TSP_PhotonArray[index] = TSP_photon;
index++;
} //if
} //if thresh
} // while TSP
} //if thresh
} // while IU
Thats all I have at the moment... work in progress, I realize all of the braces aren't closed. This is just a simple logic question.
This may take a few iterations.
As a particle physicist, you should understand the importance of breaking things down into their component parts. Let's start with iterating over all TSP photons. It looks as if the relevant code is here:
TIter photonIterTSP(mPhotonArray[1]);
while(TSP_photon=(EEmcParticleCandidate_t*)photonIterTSP.Next()) {
...
if(a certain condition is met)
TSP_PhotonArray[index] = TSP_photon;
}
So TSP_photon is a pointer, you will be copying it into the array TSP_PhotonArray (if the energy of the photon exceeds a fixed threshold), and you go to a lot of trouble keeping track of which pointers have already been so copied. There is a better way, but for now let's just consider the problem of finding the best match:
distMin=1000.0;
while(TSP_photon= ... ) {
distance_1 = compute_distance_somehow();
if (distance_1 < distMin) {
distMin = distance_1;
TSP_PhotonArray[index] = TSP_photon; // <-- BAD
index++; // <-- VERY BAD
}
}
This is wrong. Suppose you find a TSP_photon with the smallest distance yet seen. You haven't yet checked all TSP photons, so this might not be the best, but you store the pointer anyway, and increment the index. Then if you find another match that's even better, you'll store that one too. Conceptually, it should be something like this:
distMin=1000.0;
best_photon_yet = NULL;
while(TSP_photon= ... ) {
distance_1 = compute_distance_somehow();
if (distance_1 < distMin) {
distMin = distance_1;
best_pointer_yet = TSP_photon;
}
}
// We've now finished searching the whole list of TSP photons.
TSP_PhotonArray[index] = best_photon_yet;
index++;
Post a comment to this answer, telling me if this makes sense; if so, we can proceed, if not, I'll try to clarify.
I'm creating a game using my own homemade gaming engine, but I'm running into trouble using lists.
I have a structure in my program called BoardState. Each of these structures has a list of BoardState pointers called children. This is because I create a tree of BoardStates for the AI of my game.
To aid in the creation of my tree, I have a function called MakeBoard. This function gets passed all the information it needs to create a new board, and then it should add the pointer to that new board to the end of the parent board's children list. Here is the relevant function, MakeBoard:
void MakeBoard(BoardState* pStartBoard, int iPiece, int iPosStart, int iPosFinish, int* pJumpArray)
{
//BoardState* pNewBoard = &NewBoard;
//pNewBoard->bPlayerTurn = !(pStartBoard->bPlayerTurn);
//NewBoard.bPlayerTurn = !(pStartBoard->bPlayerTurn);
BoardState* pNewBoard = (BoardState*)malloc(sizeof(BoardState));
pNewBoard->bPlayerTurn = !(pStartBoard->bPlayerTurn);
// Copy the BoardPositions of the starting board into the new Board.
for(int i = 0; i < 37; i++)
{
pNewBoard->posArray[i] = pStartBoard->posArray[i];
//NewBoard.posArray[i] = pStartBoard->posArray[i];
}
// Make the BoardPosition change necessary to reflect the move.
pNewBoard->posArray[iPosStart] = -1;
pNewBoard->posArray[iPosFinish] = iPiece;
//NewBoard.posArray[iPosStart] = -1;
//NewBoard.posArray[iPosFinish] = iPiece;
// Now account for any pieces that were jumped, if applicable.
if(pJumpArray != NULL)
{
for(int i = 0; i < 16; i++)
{
if(pJumpArray[i] != -1)
{
pNewBoard->posArray[pJumpArray[i]] = -1;
//NewBoard.posArray[pJumpArray[i]] = -1;
}
}
}
// Connect the parent board to this child board.
pNewBoard->parent = pStartBoard;
//NewBoard.parent = pStartBoard;
//pStartBoard->children.push_back(_pTestState);
pStartBoard->children.push_back(pNewBoard); // <- The problem
//pStartBoard->children.push_back(&NewBoard);
}
The extra commented parts are where I was trying out other ideas to see if they worked.
Unfortunately this causes the program to throw the following error:
Access violation reading location 0xcdcdcdd1.
If I dig into the debugger, I find out that the problem is occurring in the STL list file. These are the top three calls in the call stack:
OpenGL_Engine_Test1.exe!std::list >::_Insert(std::list >::_Const_iterator<1> _Where=..., tagBoardState * const & _Val=0x049a1a80) Line 718 + 0x10 bytes C++
OpenGL_Engine_Test1.exe!std::list<tagBoardState *,std::allocator<tagBoardState *> >::push_back(tagBoardState * const & _Val=0x049a1a80) Line 670 + 0x51 bytes C++
OpenGL_Engine_Test1.exe!MakeBoard(tagBoardState * pStartBoard=0x049a0580, int iPiece=16, int iPosStart=21, int iPosFinish=16, int * pJumpArray=0x00000000) Line 352 C++
It then opens up the file where list is defined, and points out the problem line inside the _insert function:
void _Insert(const_iterator _Where,
const _Ty& _Val)
{ // insert _Val at _Where
#if _HAS_ITERATOR_DEBUGGING
if (_Where._Mycont != this)
_DEBUG_ERROR("list insert iterator outside range");
#endif /* _HAS_ITERATOR_DEBUGGING */
_Nodeptr _Pnode = _Where._Mynode();
_Nodeptr _Newnode = _Buynode(_Pnode, _Prevnode(_Pnode), _Val); // PROBLEM
_Incsize(1);
_Prevnode(_Pnode) = _Newnode;
_Nextnode(_Prevnode(_Newnode)) = _Newnode;
}
Beyond this, i don't really know more. I have no idea why this problem is occurring. I know that an "Access Violation" basically means that I'm either trying to access something that doesn't exist, I don't have access to, or there is some sort of scope problem, but I can't see how any of those are applicable.
If anyone can point me in the right direction, I would really appreciate it. I've done a lot of searching, but almost everything I've found has been pertaining to Vectors and haven't seemed to be my issue exactly.
If you malloc() a C++ class, no constructors will be called for any of that class's fields, including your problem vector. You need to use new.
I've made an assumption that pStartBoard was allocated the same as pNewBoard, but you will have the same problem in pNewBoard even if this is not the case.
Access violation reading location 0xcdcdcdd1. Indicates an unitialized variable. The debugger puts in values like that as markers. Unfortunately, I can't deduce where you are seeing the error, nor any STL containers in your code sample. But 'pNewBoard->posArray' would be the first place I look. Does that class's constructor set that member to something?