Пример #1
0
NodeList
Element::getElementsByTagName (const DOMString& name)
{
    NodeList elements;
    
    for (size_t i = 0; i < _children.length(); i++) {
        Node* node = _children.item(i);

        if (node->nodeType() == Node::ELEMENT_NODE) {
            if (((Element*)node)->tagName() == Utils::toUpper(name)) {
                elements.insert(node);
            }
        }
    }

    for (size_t i = 0; i < _children.length(); i++) {
        Node* node = _children.item(i);

        if (node->nodeType() == Node::ELEMENT_NODE) {
            NodeList subElements = ((Element*)node)->getElementsByTagName(name);

            for (size_t h = 0; h < subElements.length(); h++) {
                elements.insert(subElements.item(h));
            }
        }
    }

    return elements;
}
static void chaseDownPredecessors(iterator node, Register value,
	DataflowGraph* dfg,
	dataflow_iterator block, NodeList& nodes,
	InstructionToNodeMap& instructionToNodes, BlockSet& visited)
{
	if(!visited.insert(block).second) return;
	
	assert(block->aliveIn().count(value) != 0);

	for(auto predecessor : block->predecessors())
	{
		if(predecessor->aliveOut().count(value) == 0) continue;
		
		bool foundAnyDefinitions = false;
		
		// check the body for a definition
		for(auto instruction = predecessor->instructions().rbegin();
			instruction != predecessor->instructions().rend(); ++instruction)
		{
			for(auto destination : instruction->d)
			{
				if(*destination.pointer == value)
				{
					auto producer = nodes.end();
					
					auto ptx = static_cast<PTXInstruction*>(instruction->i);
					
					auto existingNode = instructionToNodes.find(ptx);
		
					if(existingNode == instructionToNodes.end())
					{
						producer = nodes.insert(nodes.end(), Node(ptx));
						
						instructionToNodes.insert(
							std::make_pair(ptx, producer));
					}
					else
					{
						producer = existingNode->second;
					}
					
					report(" " << producer->instruction->toString() << " -> "
						<< node->instruction->toString());
					
					node->predecessors.push_back(producer);
					producer->successors.push_back(node);
					
					foundAnyDefinitions = true;
					break;
				}
			}
		}
		
		if(foundAnyDefinitions) continue;
		
		// if no definitions were found, recurse through predecessors
		chaseDownPredecessors(node, value, dfg, predecessor, nodes,
			instructionToNodes, visited);
	}
}
 void push(int v) {
     Edge* now = net[v][cur[v]];
     double flow = min(now->cap(v), e[v]);
     int w = now->other(v);
     if ( zr(e[w]) && w != t)
         lst.insert(w, h[w]);
     now->addFlow(v, flow);
     e[v] -= flow;
     e[w] += flow;
 }
static void analyzeBlock(dataflow_iterator block, DataflowGraph* dfg,
	NodeList& nodes, InstructionToNodeMap& instructionToNodes)
{
	typedef std::unordered_map<Register, iterator> RegisterToProducerMap;
	
	RegisterToProducerMap lastProducers;
	
	for(auto& instruction : block->instructions())
	{
		// Create a node
		auto node = nodes.end();
		
		auto ptx = static_cast<PTXInstruction*>(instruction.i);
		
		auto existingNode = instructionToNodes.find(ptx);
		
		if(existingNode == instructionToNodes.end())
		{
			node = nodes.insert(nodes.end(), Node(ptx));
		
			instructionToNodes.insert(std::make_pair(ptx, node));
		}
		else
		{
			node = existingNode->second;
		}
		
		// Add predecessors
		for(auto source : instruction.s)
		{
			auto producer = lastProducers.find(*source.pointer);
		
			if(producer == lastProducers.end())
			{
				BlockSet visited;
			
				chaseDownPredecessors(node, *source.pointer, dfg, block, nodes,
					instructionToNodes, visited);
				continue;
			}
			
			report(" " << producer->second->instruction->toString() << " -> "
				<< node->instruction->toString());
			
			node->predecessors.push_back(producer->second);
			producer->second->successors.push_back(node);
		}
		
		// Update last producers
		for(auto destination : instruction.d)
		{	
			lastProducers[*destination.pointer] = node;
		}
	}
}
Пример #5
0
/** return a list of pointer to the objects of specified class type */
NodeList* NodeList::selectClass (QString classname) {
    NodeList* nl = new NodeList;
    Node* node;
    for ( QStringList::Iterator it = list_.begin(); it != list_.end(); ++it ) {
        node = find(*it);
        if (!node) {
            qDebug("NodeList::selectClass: %s Warning: %s not found in nodelist",
                   classname.latin1(),(*it).latin1());
            continue;
        }
        if (classname.compare(node->classname()) == 0) {
            nl->insert (node->key(), node );//insert node
        }
    }
    return nl;
}
Пример #6
0
static bool Graph_divide(Graph& graph, size_t loops, PositionList* position_tbl) {
    typedef std::set< size_t > NodeList;
    NodeList nodes;

    // nodes
    for (Graph::const_iterator i = graph.begin(); i != graph.end(); ++i) {
        nodes.insert(i->first);
    }

    while (!nodes.empty()) {
        // BFS
        Graph component;
        std::deque< size_t > Q = boost::assign::list_of(*nodes.begin());
        while (!Q.empty()) {
            size_t xi = Q.front();
            Q.pop_front();

            if (nodes.find(xi) == nodes.end()) {
                continue;
            }

            nodes.erase(xi);

            Graph::const_iterator i = graph.find(xi);
            if (i != graph.end()) {
                for (Children::const_iterator j = i->second.children.begin(); j != i->second.children.end(); ++j) {
                    Graph_addEdge(component, xi, j->first, j->second);
                    Q.push_back(j->first);
                }
                for (Parents::const_iterator j = i->second.parents.begin(); j != i->second.parents.end(); ++j) {
                    Q.push_back(*j);
                }
            }
        }

        LOG4CXX_TRACE(logger, boost::format("component:%d/%d") % component.size() % graph.size());

        if (!Graph_solve(component, loops, position_tbl)) {
            LOG4CXX_ERROR(logger, "solve component failed");
            return false;
        }
    }

    return true;
}
Пример #7
0
NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
      NodeAddr<RefNode*> RefA, bool FullChain, const RegisterSet &DefRRs) {
  SetVector<NodeId> DefQ;
  SetVector<NodeId> Owners;

  // The initial queue should not have reaching defs for shadows. The
  // whole point of a shadow is that it will have a reaching def that
  // is not aliased to the reaching defs of the related shadows.
  NodeId Start = RefA.Id;
  auto SNA = DFG.addr<RefNode*>(Start);
  if (NodeId RD = SNA.Addr->getReachingDef())
    DefQ.insert(RD);

  // Collect all the reaching defs, going up until a phi node is encountered,
  // or there are no more reaching defs. From this set, the actual set of
  // reaching defs will be selected.
  // The traversal upwards must go on until a covering def is encountered.
  // It is possible that a collection of non-covering (individually) defs
  // will be sufficient, but keep going until a covering one is found.
  for (unsigned i = 0; i < DefQ.size(); ++i) {
    auto TA = DFG.addr<DefNode*>(DefQ[i]);
    if (TA.Addr->getFlags() & NodeAttrs::PhiRef)
      continue;
    // Stop at the covering/overwriting def of the initial register reference.
    RegisterRef RR = TA.Addr->getRegRef();
    if (RAI.covers(RR, RefRR)) {
      uint16_t Flags = TA.Addr->getFlags();
      if (!(Flags & NodeAttrs::Preserving))
        continue;
    }
    // Get the next level of reaching defs. This will include multiple
    // reaching defs for shadows.
    for (auto S : DFG.getRelatedRefs(TA.Addr->getOwner(DFG), TA))
      if (auto RD = NodeAddr<RefNode*>(S).Addr->getReachingDef())
        DefQ.insert(RD);
  }

  // Remove all non-phi defs that are not aliased to RefRR, and collect
  // the owners of the remaining defs.
  SetVector<NodeId> Defs;
  for (auto N : DefQ) {
    auto TA = DFG.addr<DefNode*>(N);
    bool IsPhi = TA.Addr->getFlags() & NodeAttrs::PhiRef;
    if (!IsPhi && !RAI.alias(RefRR, TA.Addr->getRegRef()))
      continue;
    Defs.insert(TA.Id);
    Owners.insert(TA.Addr->getOwner(DFG).Id);
  }

  // Return the MachineBasicBlock containing a given instruction.
  auto Block = [this] (NodeAddr<InstrNode*> IA) -> MachineBasicBlock* {
    if (IA.Addr->getKind() == NodeAttrs::Stmt)
      return NodeAddr<StmtNode*>(IA).Addr->getCode()->getParent();
    assert(IA.Addr->getKind() == NodeAttrs::Phi);
    NodeAddr<PhiNode*> PA = IA;
    NodeAddr<BlockNode*> BA = PA.Addr->getOwner(DFG);
    return BA.Addr->getCode();
  };
  // Less(A,B) iff instruction A is further down in the dominator tree than B.
  auto Less = [&Block,this] (NodeId A, NodeId B) -> bool {
    if (A == B)
      return false;
    auto OA = DFG.addr<InstrNode*>(A), OB = DFG.addr<InstrNode*>(B);
    MachineBasicBlock *BA = Block(OA), *BB = Block(OB);
    if (BA != BB)
      return MDT.dominates(BB, BA);
    // They are in the same block.
    bool StmtA = OA.Addr->getKind() == NodeAttrs::Stmt;
    bool StmtB = OB.Addr->getKind() == NodeAttrs::Stmt;
    if (StmtA) {
      if (!StmtB)   // OB is a phi and phis dominate statements.
        return true;
      auto CA = NodeAddr<StmtNode*>(OA).Addr->getCode();
      auto CB = NodeAddr<StmtNode*>(OB).Addr->getCode();
      // The order must be linear, so tie-break such equalities.
      if (CA == CB)
        return A < B;
      return MDT.dominates(CB, CA);
    } else {
      // OA is a phi.
      if (StmtB)
        return false;
      // Both are phis. There is no ordering between phis (in terms of
      // the data-flow), so tie-break this via node id comparison.
      return A < B;
    }
  };

  std::vector<NodeId> Tmp(Owners.begin(), Owners.end());
  std::sort(Tmp.begin(), Tmp.end(), Less);

  // The vector is a list of instructions, so that defs coming from
  // the same instruction don't need to be artificially ordered.
  // Then, when computing the initial segment, and iterating over an
  // instruction, pick the defs that contribute to the covering (i.e. is
  // not covered by previously added defs). Check the defs individually,
  // i.e. first check each def if is covered or not (without adding them
  // to the tracking set), and then add all the selected ones.

  // The reason for this is this example:
  // *d1<A>, *d2<B>, ... Assume A and B are aliased (can happen in phi nodes).
  // *d3<C>              If A \incl BuC, and B \incl AuC, then *d2 would be
  //                     covered if we added A first, and A would be covered
  //                     if we added B first.

  NodeList RDefs;
  RegisterSet RRs = DefRRs;

  auto DefInSet = [&Defs] (NodeAddr<RefNode*> TA) -> bool {
    return TA.Addr->getKind() == NodeAttrs::Def &&
           Defs.count(TA.Id);
  };
  for (auto T : Tmp) {
    if (!FullChain && RAI.covers(RRs, RefRR))
      break;
    auto TA = DFG.addr<InstrNode*>(T);
    bool IsPhi = DFG.IsCode<NodeAttrs::Phi>(TA);
    NodeList Ds;
    for (NodeAddr<DefNode*> DA : TA.Addr->members_if(DefInSet, DFG)) {
      auto QR = DA.Addr->getRegRef();
      // Add phi defs even if they are covered by subsequent defs. This is
      // for cases where the reached use is not covered by any of the defs
      // encountered so far: the phi def is needed to expose the liveness
      // of that use to the entry of the block.
      // Example:
      //   phi d1<R3>(,d2,), ...  Phi def d1 is covered by d2.
      //   d2<R3>(d1,,u3), ...
      //   ..., u3<D1>(d2)        This use needs to be live on entry.
      if (FullChain || IsPhi || !RAI.covers(RRs, QR))
        Ds.push_back(DA);
    }
    RDefs.insert(RDefs.end(), Ds.begin(), Ds.end());
    for (NodeAddr<DefNode*> DA : Ds) {
      // When collecting a full chain of definitions, do not consider phi
      // defs to actually define a register.
      uint16_t Flags = DA.Addr->getFlags();
      if (!FullChain || !(Flags & NodeAttrs::PhiRef))
        if (!(Flags & NodeAttrs::Preserving))
          RRs.insert(DA.Addr->getRegRef());
    }
  }

  return RDefs;
}
Пример #8
0
void Liveness::computePhiInfo() {
  RealUseMap.clear();

  NodeList Phis;
  NodeAddr<FuncNode*> FA = DFG.getFunc();
  auto Blocks = FA.Addr->members(DFG);
  for (NodeAddr<BlockNode*> BA : Blocks) {
    auto Ps = BA.Addr->members_if(DFG.IsCode<NodeAttrs::Phi>, DFG);
    Phis.insert(Phis.end(), Ps.begin(), Ps.end());
  }

  // phi use -> (map: reaching phi -> set of registers defined in between)
  std::map<NodeId,std::map<NodeId,RegisterSet>> PhiUp;
  std::vector<NodeId> PhiUQ;  // Work list of phis for upward propagation.

  // Go over all phis.
  for (NodeAddr<PhiNode*> PhiA : Phis) {
    // Go over all defs and collect the reached uses that are non-phi uses
    // (i.e. the "real uses").
    auto &RealUses = RealUseMap[PhiA.Id];
    auto PhiRefs = PhiA.Addr->members(DFG);

    // Have a work queue of defs whose reached uses need to be found.
    // For each def, add to the queue all reached (non-phi) defs.
    SetVector<NodeId> DefQ;
    NodeSet PhiDefs;
    for (auto R : PhiRefs) {
      if (!DFG.IsRef<NodeAttrs::Def>(R))
        continue;
      DefQ.insert(R.Id);
      PhiDefs.insert(R.Id);
    }
    for (unsigned i = 0; i < DefQ.size(); ++i) {
      NodeAddr<DefNode*> DA = DFG.addr<DefNode*>(DefQ[i]);
      NodeId UN = DA.Addr->getReachedUse();
      while (UN != 0) {
        NodeAddr<UseNode*> A = DFG.addr<UseNode*>(UN);
        if (!(A.Addr->getFlags() & NodeAttrs::PhiRef))
          RealUses[getRestrictedRegRef(A)].insert(A.Id);
        UN = A.Addr->getSibling();
      }
      NodeId DN = DA.Addr->getReachedDef();
      while (DN != 0) {
        NodeAddr<DefNode*> A = DFG.addr<DefNode*>(DN);
        for (auto T : DFG.getRelatedRefs(A.Addr->getOwner(DFG), A)) {
          uint16_t Flags = NodeAddr<DefNode*>(T).Addr->getFlags();
          // Must traverse the reached-def chain. Consider:
          //   def(D0) -> def(R0) -> def(R0) -> use(D0)
          // The reachable use of D0 passes through a def of R0.
          if (!(Flags & NodeAttrs::PhiRef))
            DefQ.insert(T.Id);
        }
        DN = A.Addr->getSibling();
      }
    }
    // Filter out these uses that appear to be reachable, but really
    // are not. For example:
    //
    // R1:0 =          d1
    //      = R1:0     u2     Reached by d1.
    //   R0 =          d3
    //      = R1:0     u4     Still reached by d1: indirectly through
    //                        the def d3.
    //   R1 =          d5
    //      = R1:0     u6     Not reached by d1 (covered collectively
    //                        by d3 and d5), but following reached
    //                        defs and uses from d1 will lead here.
    auto HasDef = [&PhiDefs] (NodeAddr<DefNode*> DA) -> bool {
      return PhiDefs.count(DA.Id);
    };
    for (auto UI = RealUses.begin(), UE = RealUses.end(); UI != UE; ) {
      // For each reached register UI->first, there is a set UI->second, of
      // uses of it. For each such use, check if it is reached by this phi,
      // i.e. check if the set of its reaching uses intersects the set of
      // this phi's defs.
      auto &Uses = UI->second;
      for (auto I = Uses.begin(), E = Uses.end(); I != E; ) {
        auto UA = DFG.addr<UseNode*>(*I);
        NodeList RDs = getAllReachingDefs(UI->first, UA);
        if (std::any_of(RDs.begin(), RDs.end(), HasDef))
          ++I;
        else
          I = Uses.erase(I);
      }
      if (Uses.empty())
        UI = RealUses.erase(UI);
      else
        ++UI;
    }

    // If this phi reaches some "real" uses, add it to the queue for upward
    // propagation.
    if (!RealUses.empty())
      PhiUQ.push_back(PhiA.Id);

    // Go over all phi uses and check if the reaching def is another phi.
    // Collect the phis that are among the reaching defs of these uses.
    // While traversing the list of reaching defs for each phi use, collect
    // the set of registers defined between this phi (Phi) and the owner phi
    // of the reaching def.
    for (auto I : PhiRefs) {
      if (!DFG.IsRef<NodeAttrs::Use>(I))
        continue;
      NodeAddr<UseNode*> UA = I;
      auto &UpMap = PhiUp[UA.Id];
      RegisterSet DefRRs;
      for (NodeAddr<DefNode*> DA : getAllReachingDefs(UA)) {
        if (DA.Addr->getFlags() & NodeAttrs::PhiRef)
          UpMap[DA.Addr->getOwner(DFG).Id] = DefRRs;
        else
          DefRRs.insert(DA.Addr->getRegRef());
      }
    }
  }

  if (Trace) {
    dbgs() << "Phi-up-to-phi map:\n";
    for (auto I : PhiUp) {
      dbgs() << "phi " << Print<NodeId>(I.first, DFG) << " -> {";
      for (auto R : I.second)
        dbgs() << ' ' << Print<NodeId>(R.first, DFG)
               << Print<RegisterSet>(R.second, DFG);
      dbgs() << " }\n";
    }
  }

  // Propagate the reached registers up in the phi chain.
  //
  // The following type of situation needs careful handling:
  //
  //   phi d1<R1:0>  (1)
  //        |
  //   ... d2<R1>
  //        |
  //   phi u3<R1:0>  (2)
  //        |
  //   ... u4<R1>
  //
  // The phi node (2) defines a register pair R1:0, and reaches a "real"
  // use u4 of just R1. The same phi node is also known to reach (upwards)
  // the phi node (1). However, the use u4 is not reached by phi (1),
  // because of the intervening definition d2 of R1. The data flow between
  // phis (1) and (2) is restricted to R1:0 minus R1, i.e. R0.
  //
  // When propagating uses up the phi chains, get the all reaching defs
  // for a given phi use, and traverse the list until the propagated ref
  // is covered, or until or until reaching the final phi. Only assume
  // that the reference reaches the phi in the latter case.

  for (unsigned i = 0; i < PhiUQ.size(); ++i) {
    auto PA = DFG.addr<PhiNode*>(PhiUQ[i]);
    auto &RealUses = RealUseMap[PA.Id];
    for (auto U : PA.Addr->members_if(DFG.IsRef<NodeAttrs::Use>, DFG)) {
      NodeAddr<UseNode*> UA = U;
      auto &UpPhis = PhiUp[UA.Id];
      for (auto UP : UpPhis) {
        bool Changed = false;
        auto &MidDefs = UP.second;
        // Collect the set UpReached of uses that are reached by the current
        // phi PA, and are not covered by any intervening def between PA and
        // the upward phi UP.
        RegisterSet UpReached;
        for (auto T : RealUses) {
          if (!isRestricted(PA, UA, T.first))
            continue;
          if (!RAI.covers(MidDefs, T.first))
            UpReached.insert(T.first);
        }
        if (UpReached.empty())
          continue;
        // Update the set PRUs of real uses reached by the upward phi UP with
        // the actual set of uses (UpReached) that the UP phi reaches.
        auto &PRUs = RealUseMap[UP.first];
        for (auto R : UpReached) {
          unsigned Z = PRUs[R].size();
          PRUs[R].insert(RealUses[R].begin(), RealUses[R].end());
          Changed |= (PRUs[R].size() != Z);
        }
        if (Changed)
          PhiUQ.push_back(UP.first);
      }
    }
  }

  if (Trace) {
    dbgs() << "Real use map:\n";
    for (auto I : RealUseMap) {
      dbgs() << "phi " << Print<NodeId>(I.first, DFG);
      NodeAddr<PhiNode*> PA = DFG.addr<PhiNode*>(I.first);
      NodeList Ds = PA.Addr->members_if(DFG.IsRef<NodeAttrs::Def>, DFG);
      if (!Ds.empty()) {
        RegisterRef RR = NodeAddr<DefNode*>(Ds[0]).Addr->getRegRef();
        dbgs() << '<' << Print<RegisterRef>(RR, DFG) << '>';
      } else {
        dbgs() << "<noreg>";
      }
      dbgs() << " -> " << Print<RefMap>(I.second, DFG) << '\n';
    }
  }
}
Пример #9
0
int main(int argc, char** argv) {
    NodeList<int> llista;
    OrderedList<int> llistaOrd;
    cout << "Vols introduir les dades per consola o per fitxer (C/F)?" << endl;
    if(cin.get() == 'F') {
        FILE * pFile;
        pFile = fopen("fitxer.txt" , "r");
        
        int n;
        ifstream fe("fitxer.txt");
        while (scanf("%d", &n) == 1) {
            llista.insert(n);
            llistaOrd.insert(n);
        }
    }
    else {
        cout << "Introdueix una seqüència de nombres acabada per 99:" << endl;
        int aux;
        cin >> aux;
        while(aux != 99) {
            llista.insert(aux);
            llistaOrd.insert(aux);
            cin >> aux;
        }
    }
    cout << "Llista: ";
    llista.show();
    cout << "Llista Ordenada: ";
    llistaOrd.show();
    cout << endl << "Introdueix un nombre a cercar:" << endl;
    cin >> aux;
    cout << "Nombres posteriors a " << aux << " a la llista:" << endl;
    llista.begin();
    bool trobat = false;
    while(!llista.end()) {
        if(trobat) {
            cout << llista.get() << "  " ; 
        }
        else {
            if(llista.get() == aux) trobat = true;
        }
        llista.next();
    }
    cout << endl << "Nombres posteriors a " << aux << " a la llista ordenada:" <<endl;  
    trobat = false;
    llistaOrd.begin();
    while(!llistaOrd.end()) {
        if(trobat) {
            cout << llistaOrd.get() << "  " ; 
        }
        else {
            if(llistaOrd.get() == aux) trobat = true;
        }
        llistaOrd.next();
    }    
    cout << endl << "Llista esborrada i recursos alliberats" << endl;
    llista.begin();
    while(!llista.end()) {
        llista.remove();
    }
    cout << "Llista ordenada esborrada i recursos alliberats:" << endl;
    llistaOrd.begin();
    while(!llistaOrd.end()) {
        
        llistaOrd.remove();
    }
    cout << "Llista:" << endl;
    llista.show();
    cout << "Llista ordenada:" << endl;
    llistaOrd.show();
    return 0;
}
Пример #10
0
void Liveness::computePhiInfo() {
  RealUseMap.clear();

  NodeList Phis;
  NodeAddr<FuncNode*> FA = DFG.getFunc();
  NodeList Blocks = FA.Addr->members(DFG);
  for (NodeAddr<BlockNode*> BA : Blocks) {
    auto Ps = BA.Addr->members_if(DFG.IsCode<NodeAttrs::Phi>, DFG);
    Phis.insert(Phis.end(), Ps.begin(), Ps.end());
  }

  // phi use -> (map: reaching phi -> set of registers defined in between)
  std::map<NodeId,std::map<NodeId,RegisterAggr>> PhiUp;
  std::vector<NodeId> PhiUQ;  // Work list of phis for upward propagation.

  // Go over all phis.
  for (NodeAddr<PhiNode*> PhiA : Phis) {
    // Go over all defs and collect the reached uses that are non-phi uses
    // (i.e. the "real uses").
    RefMap &RealUses = RealUseMap[PhiA.Id];
    NodeList PhiRefs = PhiA.Addr->members(DFG);

    // Have a work queue of defs whose reached uses need to be found.
    // For each def, add to the queue all reached (non-phi) defs.
    SetVector<NodeId> DefQ;
    NodeSet PhiDefs;
    for (NodeAddr<RefNode*> R : PhiRefs) {
      if (!DFG.IsRef<NodeAttrs::Def>(R))
        continue;
      DefQ.insert(R.Id);
      PhiDefs.insert(R.Id);
    }

    // Collect the super-set of all possible reached uses. This set will
    // contain all uses reached from this phi, either directly from the
    // phi defs, or (recursively) via non-phi defs reached by the phi defs.
    // This set of uses will later be trimmed to only contain these uses that
    // are actually reached by the phi defs.
    for (unsigned i = 0; i < DefQ.size(); ++i) {
      NodeAddr<DefNode*> DA = DFG.addr<DefNode*>(DefQ[i]);
      // Visit all reached uses. Phi defs should not really have the "dead"
      // flag set, but check it anyway for consistency.
      bool IsDead = DA.Addr->getFlags() & NodeAttrs::Dead;
      NodeId UN = !IsDead ? DA.Addr->getReachedUse() : 0;
      while (UN != 0) {
        NodeAddr<UseNode*> A = DFG.addr<UseNode*>(UN);
        uint16_t F = A.Addr->getFlags();
        if ((F & (NodeAttrs::Undef | NodeAttrs::PhiRef)) == 0) {
          RegisterRef R = PRI.normalize(A.Addr->getRegRef(DFG));
          RealUses[R.Reg].insert({A.Id,R.Mask});
        }
        UN = A.Addr->getSibling();
      }
      // Visit all reached defs, and add them to the queue. These defs may
      // override some of the uses collected here, but that will be handled
      // later.
      NodeId DN = DA.Addr->getReachedDef();
      while (DN != 0) {
        NodeAddr<DefNode*> A = DFG.addr<DefNode*>(DN);
        for (auto T : DFG.getRelatedRefs(A.Addr->getOwner(DFG), A)) {
          uint16_t Flags = NodeAddr<DefNode*>(T).Addr->getFlags();
          // Must traverse the reached-def chain. Consider:
          //   def(D0) -> def(R0) -> def(R0) -> use(D0)
          // The reachable use of D0 passes through a def of R0.
          if (!(Flags & NodeAttrs::PhiRef))
            DefQ.insert(T.Id);
        }
        DN = A.Addr->getSibling();
      }
    }
    // Filter out these uses that appear to be reachable, but really
    // are not. For example:
    //
    // R1:0 =          d1
    //      = R1:0     u2     Reached by d1.
    //   R0 =          d3
    //      = R1:0     u4     Still reached by d1: indirectly through
    //                        the def d3.
    //   R1 =          d5
    //      = R1:0     u6     Not reached by d1 (covered collectively
    //                        by d3 and d5), but following reached
    //                        defs and uses from d1 will lead here.
    auto InPhiDefs = [&PhiDefs] (NodeAddr<DefNode*> DA) -> bool {
      return PhiDefs.count(DA.Id);
    };
    for (auto UI = RealUses.begin(), UE = RealUses.end(); UI != UE; ) {
      // For each reached register UI->first, there is a set UI->second, of
      // uses of it. For each such use, check if it is reached by this phi,
      // i.e. check if the set of its reaching uses intersects the set of
      // this phi's defs.
      NodeRefSet &Uses = UI->second;
      for (auto I = Uses.begin(), E = Uses.end(); I != E; ) {
        auto UA = DFG.addr<UseNode*>(I->first);
        // Undef flag is checked above.
        assert((UA.Addr->getFlags() & NodeAttrs::Undef) == 0);
        RegisterRef R(UI->first, I->second);
        NodeList RDs = getAllReachingDefs(R, UA);
        // If none of the reaching defs of R are from this phi, remove this
        // use of R.
        I = any_of(RDs, InPhiDefs) ? std::next(I) : Uses.erase(I);
      }
      UI = Uses.empty() ? RealUses.erase(UI) : std::next(UI);
    }

    // If this phi reaches some "real" uses, add it to the queue for upward
    // propagation.
    if (!RealUses.empty())
      PhiUQ.push_back(PhiA.Id);

    // Go over all phi uses and check if the reaching def is another phi.
    // Collect the phis that are among the reaching defs of these uses.
    // While traversing the list of reaching defs for each phi use, accumulate
    // the set of registers defined between this phi (PhiA) and the owner phi
    // of the reaching def.
    NodeSet SeenUses;

    for (auto I : PhiRefs) {
      if (!DFG.IsRef<NodeAttrs::Use>(I) || SeenUses.count(I.Id))
        continue;
      NodeAddr<PhiUseNode*> PUA = I;
      if (PUA.Addr->getReachingDef() == 0)
        continue;

      RegisterRef UR = PUA.Addr->getRegRef(DFG);
      NodeList Ds = getAllReachingDefs(UR, PUA, true, false, NoRegs);
      RegisterAggr DefRRs(PRI);

      for (NodeAddr<DefNode*> D : Ds) {
        if (D.Addr->getFlags() & NodeAttrs::PhiRef) {
          NodeId RP = D.Addr->getOwner(DFG).Id;
          std::map<NodeId,RegisterAggr> &M = PhiUp[PUA.Id];
          auto F = M.find(RP);
          if (F == M.end())
            M.insert(std::make_pair(RP, DefRRs));
          else
            F->second.insert(DefRRs);
        }
        DefRRs.insert(D.Addr->getRegRef(DFG));
      }

      for (NodeAddr<PhiUseNode*> T : DFG.getRelatedRefs(PhiA, PUA))
        SeenUses.insert(T.Id);
    }
  }

  if (Trace) {
    dbgs() << "Phi-up-to-phi map with intervening defs:\n";
    for (auto I : PhiUp) {
      dbgs() << "phi " << Print<NodeId>(I.first, DFG) << " -> {";
      for (auto R : I.second)
        dbgs() << ' ' << Print<NodeId>(R.first, DFG)
               << Print<RegisterAggr>(R.second, DFG);
      dbgs() << " }\n";
    }
  }

  // Propagate the reached registers up in the phi chain.
  //
  // The following type of situation needs careful handling:
  //
  //   phi d1<R1:0>  (1)
  //        |
  //   ... d2<R1>
  //        |
  //   phi u3<R1:0>  (2)
  //        |
  //   ... u4<R1>
  //
  // The phi node (2) defines a register pair R1:0, and reaches a "real"
  // use u4 of just R1. The same phi node is also known to reach (upwards)
  // the phi node (1). However, the use u4 is not reached by phi (1),
  // because of the intervening definition d2 of R1. The data flow between
  // phis (1) and (2) is restricted to R1:0 minus R1, i.e. R0.
  //
  // When propagating uses up the phi chains, get the all reaching defs
  // for a given phi use, and traverse the list until the propagated ref
  // is covered, or until reaching the final phi. Only assume that the
  // reference reaches the phi in the latter case.

  for (unsigned i = 0; i < PhiUQ.size(); ++i) {
    auto PA = DFG.addr<PhiNode*>(PhiUQ[i]);
    NodeList PUs = PA.Addr->members_if(DFG.IsRef<NodeAttrs::Use>, DFG);
    RefMap &RUM = RealUseMap[PA.Id];

    for (NodeAddr<UseNode*> UA : PUs) {
      std::map<NodeId,RegisterAggr> &PUM = PhiUp[UA.Id];
      RegisterRef UR = PRI.normalize(UA.Addr->getRegRef(DFG));
      for (const std::pair<NodeId,RegisterAggr> &P : PUM) {
        bool Changed = false;
        const RegisterAggr &MidDefs = P.second;

        // Collect the set PropUp of uses that are reached by the current
        // phi PA, and are not covered by any intervening def between the
        // currently visited use UA and the the upward phi P.

        if (MidDefs.hasCoverOf(UR))
          continue;

        // General algorithm:
        //   for each (R,U) : U is use node of R, U is reached by PA
        //     if MidDefs does not cover (R,U)
        //       then add (R-MidDefs,U) to RealUseMap[P]
        //
        for (const std::pair<RegisterId,NodeRefSet> &T : RUM) {
          RegisterRef R = DFG.restrictRef(RegisterRef(T.first), UR);
          if (!R)
            continue;
          for (std::pair<NodeId,LaneBitmask> V : T.second) {
            RegisterRef S = DFG.restrictRef(RegisterRef(R.Reg, V.second), R);
            if (!S)
              continue;
            if (RegisterRef SS = MidDefs.clearIn(S)) {
              NodeRefSet &RS = RealUseMap[P.first][SS.Reg];
              Changed |= RS.insert({V.first,SS.Mask}).second;
            }
          }
        }

        if (Changed)
          PhiUQ.push_back(P.first);
      }
    }
  }

  if (Trace) {
    dbgs() << "Real use map:\n";
    for (auto I : RealUseMap) {
      dbgs() << "phi " << Print<NodeId>(I.first, DFG);
      NodeAddr<PhiNode*> PA = DFG.addr<PhiNode*>(I.first);
      NodeList Ds = PA.Addr->members_if(DFG.IsRef<NodeAttrs::Def>, DFG);
      if (!Ds.empty()) {
        RegisterRef RR = NodeAddr<DefNode*>(Ds[0]).Addr->getRegRef(DFG);
        dbgs() << '<' << Print<RegisterRef>(RR, DFG) << '>';
      } else {
        dbgs() << "<noreg>";
      }
      dbgs() << " -> " << Print<RefMap>(I.second, DFG) << '\n';
    }
  }
}
Пример #11
0
bool BottomUpLib::neighbour(Stack& stack){
  StackElement *el1=0;
  StackElement *el2=0;
  StackElement *el3=0;
  StackElement *el4=0;

  try {
    if (stack.count()<4) throw Stack::CleanUp(false); //	sind noch genug Werte auf dem stack?
    el1=stack.pop(); 	//Abstandswert vom stack holen
    el2=stack.pop(); 	//Richtung vom stack holen
    el3=stack.pop(); 	//nodelist Schatten vom stack holen
    el4=stack.pop(); 	//nodelist Dach vom stack holen
	  // Typen testen
    if (el1->type()!=StackElement::NUMBER || el2->type()!=StackElement::STRING || el3->type()!=StackElement::NODELIST || el4->type()!=StackElement::NODELIST)
		throw Stack::CleanUp(false);
  	//	Werte holen
    float maxdist=((StackElementNumber*)el1)->data();		//	max eudist
    QString dir=((StackElementString*)el2)->data();			//	Sonnenrichtung
    NodeList& nl2=((StackElementNodeList*)el3)->data();	//	Schatten
    NodeList& nl1=((StackElementNodeList*)el4)->data();	//	Daecher

	#ifdef DEBUGMESSAGES
	cout<<"in function neighbour"<<endl;		
	#endif

    {
      RegionSensor *rs1 = new RegionSensor();
      nl1.calcForSelect("ALL", "llx", rs1);
      nl1.calcForSelect("ALL", "lly", rs1);
      nl1.calcForSelect("ALL", "urx", rs1);
      nl1.calcForSelect("ALL", "ury", rs1);
      nl1.calcForSelect("ALL", "area", rs1);
       delete rs1;
      RegionSensor *rs2 = new RegionSensor();
      nl2.calcForSelect("ALL", "llx", rs2);
      nl2.calcForSelect("ALL", "lly", rs2);
      nl2.calcForSelect("ALL", "urx", rs2);
      nl2.calcForSelect("ALL", "ury", rs2);
      nl2.calcForSelect("ALL", "area", rs2);
      delete rs2;
     }
    Stack* st= new Stack;  // Ergebnis stack anlegen

    QHash<QString,Node*>::iterator it1=nl1.begin();
	// nodelist1 durchlaufen Daecher
    while ( it1!=nl1.end() ) {
      Node *node1 = it1.value();
      NodeList *nlist = new NodeList;
      GeoPosition gp(node1, 
		     node1->getValue("llx").toInt(),  
		     node1->getValue("lly").toInt(),
		     node1->getValue("urx").toInt(), 
		     node1->getValue("ury").toInt(), 
		     node1->getValue("area").toFloat() );
      gp.key(it1.key());
      int shade=0;
      QHash<QString,Node*>::iterator it2=nl2.begin();
      // nodelist2 durchlaufen Schattenbereiche
      while ( it2!=nl2.end() ) {
      	Node *node2 = it2.value();
	if (gp.bbOverlap(GeoPosition (node2, 
				      node2->getValue("llx").toInt(),  
				      node2->getValue("lly").toInt(),
				      node2->getValue("urx").toInt(), 
				      node2->getValue("ury").toInt(),
				      node2->getValue("area").toFloat() ),
			 dir, maxdist)){
	  if (!shade){
#ifdef DEBUGMESSAGES
	    cout<<"Haus in nodelist eingehaengt"<<endl;		
#endif //DEBUGMESSAGES
//	insert node1 Haus
	    nlist->insert(node1->value("addr"), node1 );	
	    shade=1;
	  }
	  //	insert node2 Schatten
	  nlist->insert(node2->value("addr"), node2 );	
#ifdef DEBUGMESSAGES
	  cout<<"Schatten in nodelist eingehaengt"<<endl;		
#endif //DEBUGMESSAGES
	}
	++it2;
      }
      if (shade){
	st->push(new StackElementNodeList(*nlist));
#ifdef DEBUGMESSAGES
	cout<<"nodelist auf lokalen stack gepusht"<<endl;			
#endif //DEBUGMESSAGES
      }
      delete nlist;
      ++it1;
    }
    
    stack.push(new StackElementStack(*st));
#ifdef DEBUGMESSAGES
    cout<<"gefundene Haeuser mit Schatten:"<<st->count()<<" auf globalen Stack gepusht"<<endl;
#endif //DEBUGMESSAGES
    delete st;
    throw Stack::CleanUp(true);
  }
  catch(Stack::CleanUp e) {
    if (el1) delete el1;
    if (el2) delete el2;
    if (el3) delete el3;
    if (el4) delete el4;
    return e.status_;
  }
}
Пример #12
0
 void DataFlow::mergeFlow(Graph<NodeDesc>* f,const Graph<NodeDesc>* g, std::map<Node*,Node*>& mapping)
 {
   // mapping is g -> f
   NodeList queue = g->rootNodes();
   while (!queue.empty())
   {
     Node* n = queue.back();
     queue.pop_back();
     // check predecessors
     bool allSourcesMapped = true;
     for (LinkListCIt sIt=n->sources().begin();sIt!=n->sources().end();sIt++)
     {
       Link* sLink = *sIt;
       map<Node*,Node*>::iterator findIt=mapping.find(sLink->source);
       if (findIt==mapping.end())
       {
         allSourcesMapped = false;
         break;
       }
     }
     if (!allSourcesMapped)
     {
       // some sources miss. Ignore current node for now
       continue;
     }
     if (mapping.find(n)==mapping.end())
     {
       // merge node
       // all sources are merged, merge current node
       Node* mergedNode(NULL);
       // first check if identical node already exists in f
       NodeList candidates;
       if (n->sources().size()>0)
       {
         candidates = mapping.find(n->sources()[0]->source)->second->targetNodes();
       } else {
         candidates = f->rootNodes();
       }
       for (NodeListIt cIt=candidates.begin();cIt!=candidates.end();cIt++)
       {
         if ((**cIt==*n) && sources_match(n->sources(),(*cIt)->sources(),mapping))
         {
           // found identical node
           mergedNode = *cIt;
           break;
         }
       }
       if (mergedNode==NULL)
       {
         // no identical node found. Create node
         mergedNode = f->createNode(n->v);
         for (LinkListCIt sIt=n->sources().begin();sIt!=n->sources().end();sIt++)
         {
           f->link(mapping.find((*sIt)->source)->second,(*sIt)->sourceOutputPort, mergedNode, (*sIt)->targetInputPort);
         }
       }
       // register mapping
       mapping[n] = mergedNode;
     }
     // add target nodes to queue
     NodeList targets = n->targetNodes();
     queue.insert(queue.end(),targets.begin(),targets.end());
   }
   // merge names
   for (NameMapCIt gnIt=g->getNames().begin();gnIt!=g->getNames().end();gnIt++)
   {
     NameMapCIt fnIt = f->getNames().find(gnIt->first);
     if (fnIt!=f->getNames().end()) {
       // check nodes are merged
       if (mapping[gnIt->second]!=fnIt->second) {
         cerr << "ERROR: '" << gnIt->first << "' node exists in the two graphs and cannot be merged !" << endl;
       }
     } else {
       // add named node to f
       f->setNodeName(mapping[gnIt->second], gnIt->first);
     }
   }
 }