Exemple #1
0
void BasicBlock::deepDump(const Procedure& proc, PrintStream& out) const
{
    out.print("BB", *this, ": ; frequency = ", m_frequency, "\n");
    if (predecessors().size())
        out.print("  Predecessors: ", pointerListDump(predecessors()), "\n");
    for (Value* value : *this)
        out.print("    ", B3::deepDump(proc, value), "\n");
}
Exemple #2
0
// This is the marker algorithm from "Simple and Efficient Construction of
// Static Single Assignment Form"
// The simple, non-marker algorithm places phi nodes at any join
// Here, we place markers, and only place phi nodes if they end up necessary.
// They are only necessary if they break a cycle (IE we recursively visit
// ourselves again), or we discover, while getting the value of the operands,
// that there are two or more definitions needing to be merged.
// This still will leave non-minimal form in the case of irreducible control
// flow, where phi nodes may be in cycles with themselves, but unnecessary.
MemoryAccess *MemorySSAUpdater::getPreviousDefRecursive(BasicBlock *BB) {
  // Single predecessor case, just recurse, we can only have one definition.
  if (BasicBlock *Pred = BB->getSinglePredecessor()) {
    return getPreviousDefFromEnd(Pred);
  } else if (VisitedBlocks.count(BB)) {
    // We hit our node again, meaning we had a cycle, we must insert a phi
    // node to break it so we have an operand. The only case this will
    // insert useless phis is if we have irreducible control flow.
    return MSSA->createMemoryPhi(BB);
  } else if (VisitedBlocks.insert(BB).second) {
    // Mark us visited so we can detect a cycle
    SmallVector<MemoryAccess *, 8> PhiOps;

    // Recurse to get the values in our predecessors for placement of a
    // potential phi node. This will insert phi nodes if we cycle in order to
    // break the cycle and have an operand.
    for (auto *Pred : predecessors(BB))
      PhiOps.push_back(getPreviousDefFromEnd(Pred));

    // Now try to simplify the ops to avoid placing a phi.
    // This may return null if we never created a phi yet, that's okay
    MemoryPhi *Phi = dyn_cast_or_null<MemoryPhi>(MSSA->getMemoryAccess(BB));
    bool PHIExistsButNeedsUpdate = false;
    // See if the existing phi operands match what we need.
    // Unlike normal SSA, we only allow one phi node per block, so we can't just
    // create a new one.
    if (Phi && Phi->getNumOperands() != 0)
      if (!std::equal(Phi->op_begin(), Phi->op_end(), PhiOps.begin())) {
        PHIExistsButNeedsUpdate = true;
      }

    // See if we can avoid the phi by simplifying it.
    auto *Result = tryRemoveTrivialPhi(Phi, PhiOps);
    // If we couldn't simplify, we may have to create a phi
    if (Result == Phi) {
      if (!Phi)
        Phi = MSSA->createMemoryPhi(BB);

      // These will have been filled in by the recursive read we did above.
      if (PHIExistsButNeedsUpdate) {
        std::copy(PhiOps.begin(), PhiOps.end(), Phi->op_begin());
        std::copy(pred_begin(BB), pred_end(BB), Phi->block_begin());
      } else {
        unsigned i = 0;
        for (auto *Pred : predecessors(BB))
          Phi->addIncoming(PhiOps[i++], Pred);
      }

      Result = Phi;
    }
    if (MemoryPhi *MP = dyn_cast<MemoryPhi>(Result))
      InsertedPHIs.push_back(MP);
    // Set ourselves up for the next variable by resetting visited state.
    VisitedBlocks.erase(BB);
    return Result;
  }
  llvm_unreachable("Should have hit one of the three cases above");
}
Exemple #3
0
	bool Search(U_INT src, U_INT trg, T& PathRes, U_INT& Cost) {
		typedef boost::graph_traits<GraphT>::vertex_descriptor vertex_descriptor;
		std::vector<vertex_descriptor> predecessors(num_vertices(hGraph));
		if (src>=num_vertices(hGraph) || trg>=num_vertices(hGraph)) return false;
		vertex_descriptor source_vertex = vertex(src, hGraph);
		vertex_descriptor target_vertex = vertex(trg, hGraph);
		std::vector<U_INT> distances(num_vertices(hGraph));
		typedef std::vector<boost::default_color_type> colormap_t;
		colormap_t colors(num_vertices(hGraph));
		try {
			boost::astar_search(
			    hGraph, source_vertex,
			    distance_heuristic<GraphT>(hGraph, target_vertex),
			    boost::predecessor_map(&predecessors[0]).
			    weight_map(get(( &xEdge::cost ), hGraph)).
			    distance_map(&distances[0]).
			    color_map(&colors[0]).
			    visitor(astar_goal_visitor<vertex_descriptor>(target_vertex)));
		} catch (found_goal fg) {
			Cost=distances[target_vertex];
			PathRes.clear();
			PathRes.push_front(target_vertex);
			size_t max=num_vertices(hGraph);
			while (target_vertex != source_vertex) {
				if (target_vertex == predecessors[target_vertex])
					return false;
				target_vertex = predecessors[target_vertex];
				PathRes.push_front(target_vertex);
				if (!max--)
					return false;
			}
			return true;
		}
		return false;
	}
Exemple #4
0
void BasicBlock::deepDump(const Procedure& proc, PrintStream& out) const
{
    out.print("BB", *this, ": ; frequency = ", m_frequency, "\n");
    if (predecessors().size())
        out.print("  Predecessors: ", pointerListDump(predecessors()), "\n");
    for (Value* value : *this)
        out.print("    ", B3::deepDump(proc, value), "\n");
    if (!successors().isEmpty()) {
        out.print("  Successors: ");
        if (size())
            last()->dumpSuccessors(this, out);
        else
            out.print(listDump(successors()));
        out.print("\n");
    }
}
Exemple #5
0
     result_distances bellman_ford_shortest_paths(v_index s) {
         v_index N = num_verts();

         std::vector<double> distance(N, (std::numeric_limits<double>::max)());
         std::vector<vertex_descriptor> predecessors(N);
         result_distances to_return;
         typename boost::property_map<adjacency_list, boost::edge_weight_t>::type weight = get(boost::edge_weight, (*graph));

         for (v_index i = 0; i < N; ++i)
             predecessors[i] = (*vertices)[i];

         distance[s] = 0;
         bool r = boost::bellman_ford_shortest_paths
             (*graph, N, boost::weight_map(weight).distance_map(boost::make_iterator_property_map(distance.begin(), index)).predecessor_map(boost::make_iterator_property_map(predecessors.begin(), index)));

         if (!r) {
             return to_return;
         }

         to_return.distances = distance;
         for (int i = 0; i < N; i++) {
             to_return.predecessors.push_back(index[predecessors[i]]);
         }
         return to_return;
     }
Exemple #6
0
/* Assuming the file exists and is an acyclic graph, print the vertices in a topological order
 * Use the algorithm that finds no-predecessor vertices and deletes their successor edges.
 * ALERT: modifies the graph by deleting edges.
 *
 * Solves topocycleExercise.c */
void toposort2(GraphInfo gi) {
    Graph g = gi->graph;
    int numV = numVerts(g);
    short done[numV]; // 1 if vertex already printed, otherwise 0
    for (int i = 0; i < numV; i++)
        done[i] = 0;

    for (int numPrinted = 0; numPrinted < numV; numPrinted++) {

        /* set noPred to a vertex with no predecessors and not already done */
        int noPred;
        int* ps; // predecessor list
        for (int v = 0; v < numV; v++) {
            if (!done[v]) {
                ps = predecessors(g, v);
                if (ps[0] == -1 ) { // list is empty?
                    noPred = v;
                    break;
                }
            }
        }

        /* print noPred and mark as done */
        printf("%s ", gi->vertnames[noPred]);
        done[noPred] = 1;

        /* get successors of noPred and delete them */
        int* snoPred = successors(gi->graph, noPred);
        for (int i = 0; snoPred[i] != -1; i++)
            delEdge(gi->graph, noPred, snoPred[i]);
    }

    /* cleanup */
    printf("\n");
}
Exemple #7
0
// Computes the immediate dominator of the current block.  Assumes that all of
// its predecessors have already computed their dominators.  This is achieved
// by visiting the nodes in topological order.
void BasicBlock::computeDominator() {
  BasicBlock *Candidate = nullptr;
  // Walk backwards from each predecessor to find the common dominator node.
  for (auto &Pred : predecessors()) {
    // Skip back-edges
    if (Pred->BlockID >= BlockID) continue;
    // If we don't yet have a candidate for dominator yet, take this one.
    if (Candidate == nullptr) {
      Candidate = Pred.get();
      continue;
    }
    // Walk the alternate and current candidate back to find a common ancestor.
    auto *Alternate = Pred.get();
    while (Alternate != Candidate) {
      if (!Alternate || !Candidate) {
        // TODO: warn on invalid CFG.
        Candidate = nullptr;
        break;
      }

      if (Candidate->BlockID > Alternate->BlockID)
        Candidate = Candidate->DominatorNode.Parent;
      else
        Alternate = Alternate->DominatorNode.Parent;
    }
  }
  DominatorNode.Parent = Candidate;
  DominatorNode.SizeOfSubTree = 1;
}
Exemple #8
0
    // This function works only on undirected graphs with no parallel edge.
    std::vector<v_index> prim_min_spanning_tree() {
        std::vector<v_index> to_return;
        std::vector<vertex_descriptor> predecessors(num_verts());
        prim_minimum_spanning_tree(*graph, boost::make_iterator_property_map(predecessors.begin(), index));

        for (unsigned int i = 0; i < predecessors.size(); i++) {
            if (index[predecessors[i]] != i) {
                to_return.push_back(i);
                to_return.push_back(index[predecessors[i]]);
            }
        }
        return to_return;
    }
std::vector<std::size_t> GetData(Elephants &elephants) {
  auto indices = ElephantsIndices(elephants);
  std::sort(elephants.begin(), elephants.end(), [](const Elephant &a, const Elephant &b) -> bool {
    /*if (a.weight == b.weight) {
      return a.iq < b.iq;
    }*/
    return a.weight < b.weight;
  });

  auto len = elephants.size();
  std::vector<std::size_t> lis;
  lis.reserve(len);

  std::vector<std::size_t> m;
  m.reserve(len + 1);
  m.emplace_back(0);

  std::vector<std::size_t> predecessors(len);

  for (std::size_t i = 0; i < len; ++i) {
    auto find_it = std::lower_bound(m.begin() + 1,
                                    m.end(),
                                    elephants[i],
                                    [&elephants](const std::size_t &i_m, const Elephant &elephant) -> bool {
                                      return elephants[i_m - 1].weight < elephant.weight;
                                    });
    auto i_m = std::distance(m.begin(), find_it);
    if (find_it == m.end()) {
      m.emplace_back(i + 1);
    } else {
      *find_it = i + 1;
    }

    predecessors[i] = m[i_m - 1];
  }

  for (auto i = m[m.size() - 1]; i > 0; i = predecessors[i - 1]) {
    std::cout << elephants[i - 1].Hash() << "\t" << indices[elephants[i - 1].Hash()] + 1 << std::endl;
    lis.emplace_back(indices[elephants[i - 1].Hash()] + 1);
  }

  std::reverse(lis.begin(), lis.end());
  return lis;
}
Exemple #10
0
    result_distances dijkstra_shortest_paths(v_index s) {
         v_index N = num_verts();
         result_distances to_return;
         std::vector<double> distances(N, (std::numeric_limits<double>::max)());
         std::vector<vertex_descriptor> predecessors(N);
         try {
             boost::dijkstra_shortest_paths(*graph, (*vertices)[s], distance_map(boost::make_iterator_property_map(distances.begin(), index))
                                            .predecessor_map(boost::make_iterator_property_map(predecessors.begin(), index)));
         } catch (boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::negative_edge> > e) {
             return to_return;
         }

         to_return.distances = distances;

         for (int i = 0; i < N; i++) {
             to_return.predecessors.push_back(index[predecessors[i]]);
         }

         return to_return;
     }
Exemple #11
0
// Sorts blocks in post-topological order, by following predecessors.
// Each block will be written into the Blocks array in order, and PostBlockID
// will be set to the index in the array.  Sorting should start from the exit
// block, and ID should be the total number of blocks.
int BasicBlock::postTopologicalSort(BasicBlock** Blocks, int ID) {
  if (PostBlockID != InvalidBlockID) return ID;
  PostBlockID = 0;  // mark as being visited

  // First sort the dominator, if it exists.
  // This gives us a topological order where post-dominators always come last.
  if (DominatorNode.Parent)
    ID = DominatorNode.Parent->postTopologicalSort(Blocks, ID);

  for (auto &B : predecessors()) {
    if (B.get())
      ID = B->postTopologicalSort(Blocks, ID);
  }

  // set ID and update block array in place.
  // We may lose pointers to unreachable blocks.
  assert(ID > 0);
  PostBlockID = --ID;
  Blocks[PostBlockID] = this;
  return ID;
}
Exemple #12
0
int main(int, char *[])
{
  typedef float Weight;
  typedef boost::property<boost::edge_weight_t, Weight> WeightProperty;
  typedef boost::property<boost::vertex_name_t, std::string> NameProperty;

  typedef boost::adjacency_list < boost::listS, boost::vecS, boost::directedS,
    NameProperty, WeightProperty > Graph;

  typedef boost::graph_traits < Graph >::vertex_descriptor Vertex;

  typedef boost::property_map < Graph, boost::vertex_index_t >::type IndexMap;
  typedef boost::property_map < Graph, boost::vertex_name_t >::type NameMap;

  typedef boost::iterator_property_map < Vertex*, IndexMap, Vertex, Vertex& > PredecessorMap;
  typedef boost::iterator_property_map < Weight*, IndexMap, Weight, Weight& > DistanceMap;


  // Create a graph
  Graph g;

  // Add named vertices
  Vertex v0 = add_vertex(std::string("v0"), g);
  Vertex v1 = add_vertex(std::string("v1"), g);
  Vertex v2 = add_vertex(std::string("v2"), g);
  Vertex v3 = add_vertex(std::string("v3"), g);

  // Add weighted edges
  Weight weight0 = 5;
  Weight weight1 = 3;
  Weight weight2 = 2;
  Weight weight3 = 4;

  add_edge(v0, v1, weight0, g);
  add_edge(v1, v3, weight1, g);
  add_edge(v0, v2, weight2, g);
  add_edge(v2, v3, weight3, g);

  // At this point the graph is
  /*    v0
         .
        / \ 2
       /   \
      /     . v2
    5/       \
    /         \ 4
   /           \
  v1----------- v3
      3
  */

  // Create things for Dijkstra
  std::vector<Vertex> predecessors(num_vertices(g)); // To store parents
  std::vector<Weight> distances(num_vertices(g)); // To store distances
/* works
//////////////
  IndexMap indexMap = get(boost::vertex_index, g);
  PredecessorMap predecessorMap(&predecessors[0], indexMap);
  DistanceMap distanceMap(&distances[0], indexMap);

  // Compute shortest paths from v0 to all vertices, and store the output in predecessors and distances
  boost::dijkstra_shortest_paths(g, v0, boost::predecessor_map(predecessorMap).distance_map(distanceMap));
//////////////
*/

//////////////
  IndexMap indexMap = get(boost::vertex_index, g);
  
  DistanceMap distanceMap(&distances[0], indexMap);

  PredecessorMap predecessorMap(&predecessors[0], indexMap);
  boost::predecessor_map(predecessorMap).distance_map(distanceMap);
  // Compute shortest paths from v0 to all vertices, and store the output in predecessors and distances
  boost::dijkstra_shortest_paths(g, v0, boost::predecessor_map(predecessorMap));
//////////////
  
  
  // Output results
  std::cout << "distances and parents:" << std::endl;
  NameMap nameMap = get(boost::vertex_name, g);

  BGL_FORALL_VERTICES(v, g, Graph) 
  {
    std::cout << "distance(" << nameMap[v0] << ", " << nameMap[v] << ") = " << distanceMap[v] << ", ";
    std::cout << "predecessor(" << nameMap[v] << ") = " << nameMap[predecessorMap[v]] << std::endl;
  }
/**
 * @brief Search the graph for a minimun path between originVertex and targetVertex. Returns the path
 *
 * @param originVertex ...
 * @param targetVertex ...
 * @param vertexPath std::vector of Vertex with the path
 * @return bool
 */
bool PlannerPRM::searchGraph(const Vertex &originVertex, const Vertex &targetVertex, std::vector<Vertex> &vertexPath)
{
	
	qDebug() << __FUNCTION__ << "Searching the graph between " << graph[originVertex].pose << "and " << graph[targetVertex].pose;
	
	// Create things for Dijkstra
	std::vector<Vertex> predecessors(boost::num_vertices(graph)); // To store parents
	std::vector<float> distances(boost::num_vertices(graph));     // To store distances

	//Create a vertex_index property map, since VertexList is listS
	typedef std::map<Vertex, size_t>IndexMap;
	IndexMap indexMap;
	boost::associative_property_map<IndexMap> propmapIndex(indexMap);
	
  //indexing the vertices
	int i=0;
	BGL_FORALL_VERTICES(v, graph, Graph)
		boost::put(propmapIndex, v, i++);

	auto predecessorMap = boost::make_iterator_property_map(&predecessors[0], propmapIndex);
	auto distanceMap = boost::make_iterator_property_map(&distances[0], propmapIndex);

	boost::dijkstra_shortest_paths(graph, originVertex, boost::weight_map(boost::get(&EdgePayload::dist, graph))
															.vertex_index_map(propmapIndex)
															.predecessor_map(predecessorMap)
 															.distance_map(distanceMap));

	//////////////////////////
	// Extract a shortest path
	//////////////////////////
	PathType path;
	Vertex v = targetVertex;

	//////////////////////////
	// Start by setting 'u' to the destintaion node's predecessor   |||// Keep tracking the path until we get to the source
	/////////////////////////
	for( Vertex u = predecessorMap[v]; u != v; v = u, u = predecessorMap[v]) // Set the current vertex to the current predecessor, and the predecessor to one level up
	{
		std::pair<Graph::edge_descriptor, bool> edgePair = boost::edge(u, v, graph);
		Graph::edge_descriptor edge = edgePair.first;
		path.push_back( edge );
	}

 	qDebug() << __FUNCTION__ << " Path found with length: " << path.size() << "steps and length " << 	distanceMap[targetVertex];
;
	Vertex lastVertex;
	if(path.size() > 0)
	{
		vertexPath.clear();
		for(PathType::reverse_iterator pathIterator = path.rbegin(); pathIterator != path.rend(); ++pathIterator)
		{
			vertexPath.push_back(boost::source(*pathIterator, graph));
			lastVertex = boost::target(*pathIterator, graph);
		}
		vertexPath.push_back(lastVertex);
		return true;
	}
	else
	{
		qDebug() << "Path no found between nodes";
		return false;
	}
}
Exemple #14
0
int main()
{
	Triangulation triangulation;

	boost::filesystem::path input_pathname = "C:/Carleton/CGAL-4.4/demo/Polyhedron/data/elephant.off";

	// create_cubes(triangulation, 2, 2, 1 );
	read_off( triangulation, input_pathname.string() );

	// read_off(triangulation, "C:/Carleton/Meshes/holmes_off/geometry/octahedron.off"); 
	// read_off(triangulation, "C:/Carleton/CGAL-4.4/demo/Polyhedron/data/cube.off");
	// read_off(triangulation, "C:/Carleton/CGAL-4.4/demo/Polyhedron/data/ellipsoid.off");

#if 0
	for (auto cell = triangulation.finite_cells_begin(); cell != triangulation.finite_cells_end(); ++cell)
	{
		for (int i = 0; i < 4; ++i)
		{
			Point p = cell->vertex(i)->point();
			assert(-10.0 < p.x() && p.x() < +10.0);
			assert(-10.0 < p.y() && p.y() < +10.0);
			assert(-10.0 < p.z() && p.z() < +10.0);
		}
	}
#endif

	set_cell_and_vertex_ids(triangulation);
	set_random_weights(triangulation);
	propagate_weights(triangulation);

	std::cout << "Number of finite vertices : " << triangulation.number_of_vertices() << std::endl;
	std::cout << "Number of finite edges    : " << triangulation.number_of_finite_edges() << std::endl;
	std::cout << "Number of finite facets   : " << triangulation.number_of_finite_facets() << std::endl;
	std::cout << "Number of finite cells    : " << triangulation.number_of_finite_cells() << std::endl;

	std::string filename = input_pathname.filename().stem().string() + "_tet.vtk";
	write_vtk( triangulation, filename );

	if (triangulation.number_of_finite_cells() < 100)
	{
		dump_triangulation(triangulation);
	}

	Graph graph;

	create_steiner_points(graph,triangulation);

	// the distances are temporary, so we choose an external property for that
	std::vector<double> distances(num_vertices(graph));
	std::vector<GraphNode_descriptor> predecessors(num_vertices(graph));

	boost::dijkstra_shortest_paths(
		graph, 
		*vertices(graph).first, 
		boost::weight_map(get(&GraphEdge::weight, graph)).
		distance_map(boost::make_iterator_property_map(distances.begin(), get(boost::vertex_index, graph))).
		predecessor_map(boost::make_iterator_property_map(predecessors.begin(), get(boost::vertex_index, graph)))
	);
	
	filename = input_pathname.filename().stem().string() + "_wsp.vtk";
	write_shortest_path_vtk( graph, predecessors, distances, filename );

	// write_graph_dot("graph.dot", graph);

	std::cout << "This is the end..." << std::endl;

	return EXIT_SUCCESS;
}
void BasicBlock::dumpHeader(PrintStream& out) const
{
    out.print("BB", *this, ": ; frequency = ", m_frequency, "\n");
    if (predecessors().size())
        out.print("  Predecessors: ", pointerListDump(predecessors()), "\n");
}