Ejemplo n.º 1
0
Archivo: cfg.cpp Proyecto: 191919/hhvm
TEST(CFG, InsertPreHeaders_Simple) {
  IRUnit unit{test_context};
  auto const dummy = BCMarker::Dummy();

  // Three forward edges into loop, only one back-edge.

  /*
    digraph G {
    B0 -> B1; B0 -> B2
    B1 -> B3; B1 -> B4
    B2 -> B5
    B3 -> B5
    B4 -> B5
    B5 -> B5
    }
  */

  auto b0 = unit.entry();
  auto b1 = unit.defBlock();
  auto b2 = unit.defBlock();
  auto b3 = unit.defBlock();
  auto b4 = unit.defBlock();
  auto b5 = unit.defBlock();

  auto val1 = unit.gen(Conjure, dummy, TBool);
  auto val2 = unit.gen(Conjure, dummy, TBool);

  b0->push_back(unit.gen(JmpZero, dummy, b1, val1->dst()));
  b0->back().setNext(b2);

  b1->push_back(unit.gen(JmpNZero, dummy, b3, val2->dst()));
  b1->back().setNext(b4);

  b2->push_back(unit.gen(Jmp, dummy, b5));
  b3->push_back(unit.gen(Jmp, dummy, b5));
  b4->push_back(unit.gen(Jmp, dummy, b5));
  b5->push_back(unit.gen(Jmp, dummy, b5));

  auto oldSize = unit.numBlocks();
  auto res = insertLoopPreHeaders(unit);
  auto newSize = unit.numBlocks();

  EXPECT_TRUE(res);
  EXPECT_EQ(newSize, oldSize + 1);

  // b6 is the new pre-header.
  auto b6 = b2->taken();

  EXPECT_NE(b6, b5);
  EXPECT_EQ(b6->taken(), b5);

  EXPECT_EQ(b3->taken(), b6);
  EXPECT_EQ(b4->taken(), b6);

  EXPECT_EQ(b5->taken(), b5);
}
Ejemplo n.º 2
0
bool IRInstruction::mayRaiseError() const {
  if (!opcodeHasFlags(op(), MayRaiseError)) return false;

  // Some instructions only throw if they do not have a non-catch label.
  if (is(LdClsPropAddrCached, LdClsPropAddr) &&
      taken() && !taken()->isCatch()) {
    return false;
  }

  return opcodeHasFlags(op(), MayRaiseError);
}
Ejemplo n.º 3
0
Archivo: cfg.cpp Proyecto: 191919/hhvm
TEST(CFG, InsertPreHeaders_MultiBackEdge) {
  IRUnit unit{test_context};
  auto const dummy = BCMarker::Dummy();

  // Multiple back-edges to the same block.

  /*
    digraph G {
    B0 -> B1; B0 -> B2
    B1 -> B3
    B2 -> B3
    B3 -> B3; B3 -> B4
    B4 -> B3
    }
  */

  auto b0 = unit.entry();
  auto b1 = unit.defBlock();
  auto b2 = unit.defBlock();
  auto b3 = unit.defBlock();
  auto b4 = unit.defBlock();

  auto val1 = unit.gen(Conjure, dummy, TBool);
  auto val2 = unit.gen(Conjure, dummy, TBool);

  b0->push_back(unit.gen(JmpZero, dummy, b1, val1->dst()));
  b0->back().setNext(b2);

  b1->push_back(unit.gen(Jmp, dummy, b3));
  b2->push_back(unit.gen(Jmp, dummy, b3));

  b3->push_back(unit.gen(JmpNZero, dummy, b3, val2->dst()));
  b3->back().setNext(b4);

  b4->push_back(unit.gen(Jmp, dummy, b3));

  auto oldSize = unit.numBlocks();
  auto res = insertLoopPreHeaders(unit);
  auto newSize = unit.numBlocks();

  EXPECT_TRUE(res);
  EXPECT_EQ(newSize, oldSize + 1);

  // b5 is the new pre-header.
  auto b5 = b1->taken();

  EXPECT_NE(b3, b4);
  EXPECT_EQ(b5->numSuccs(), 1);
  EXPECT_EQ(b2->taken(), b5);
  EXPECT_EQ(b5->taken(), b3);

  EXPECT_EQ(b3->taken(), b3);
  EXPECT_EQ(b4->taken(), b3);
}
Ejemplo n.º 4
0
int main(void)
{
	char *parent, *c;

	plan_tests(21);

	/* We can take NULL. */
	ok1(take(NULL) == NULL);
	ok1(is_taken(NULL));
	ok1(taken(NULL)); /* Undoes take() */
	ok1(!is_taken(NULL));
	ok1(!taken(NULL));

	parent = tal(NULL, char);
	ok1(parent);

	ok1(take(parent) == parent);
	ok1(is_taken(parent));
	ok1(taken(parent)); /* Undoes take() */
	ok1(!is_taken(parent));
	ok1(!taken(parent));

	c = tal(parent, char);
	*c = 'h';
	c = tal_dup(parent, char, take(c), 1, 0);
	ok1(c[0] == 'h');
	ok1(tal_parent(c) == parent);

	c = tal_dup(parent, char, take(c), 1, 2);
	ok1(c[0] == 'h');
	strcpy(c, "hi");
	ok1(tal_parent(c) == parent);

	/* dup must reparent child. */
	c = tal_dup(NULL, char, take(c), 1, 0);
	ok1(c[0] == 'h');
	ok1(tal_parent(c) == NULL);

	/* No leftover allocations. */
	tal_free(c);
	ok1(talloc_total_blocks(parent) == 1);

	tal_free(parent);
	ok1(!taken_any());

	/* NULL pass-through. */
	c = NULL;
	ok1(tal_dup(NULL, char, take(c), 5, 5) == NULL);
	ok1(!taken_any());

	return exit_status();
}
Ejemplo n.º 5
0
void BranchData::print_data_on(outputStream* st) {
  print_shared(st, "BranchData");
  st->print_cr("taken(%u) displacement(%d)",
               taken(), displacement());
  tab(st);
  st->print_cr("not taken(%u)", not_taken());
}
Ejemplo n.º 6
0
/*
 * Clone the `unit's CFG starting at `startBlock', and rename SSATmps
 * according to `tmpRenames' map along the way.  The new block
 * corresponding to `startBlock' is returned.  All blocks reachable
 * from `startBlock' are also cloned, so that there is no path from
 * the cloned blocks to the original blocks in the `unit'.  Note that,
 * as instructions are cloned into the new blocks, the dest SSATmps of
 * these instructions also need to be renamed, so they're added to
 * `tmpRenames' along the way.
 */
Block* cloneCFG(IRUnit& unit,
                Block* startBlock,
                jit::flat_map<SSATmp*, SSATmp*> tmpRenames) {
    jit::queue<Block*> toClone;
    boost::dynamic_bitset<> toCloneSet(unit.numBlocks());
    jit::hash_map<Block*, Block*> blockRenames;

    FTRACE(5, "cloneCFG: starting at B{}\n", startBlock->id());

    auto push = [&](Block* b) {
        if (!b || toCloneSet[b->id()]) return;
        toClone.push(b);
        toCloneSet[b->id()] = true;
    };

    // Clone each of the blocks.
    push(startBlock);
    while (!toClone.empty()) {
        auto origBlock = toClone.front();
        toClone.pop();
        auto copyBlock = unit.defBlock(origBlock->profCount(), origBlock->hint());
        blockRenames[origBlock] = copyBlock;
        FTRACE(5, "cloneCFG: copying B{} to B{}\n",
               origBlock->id(), copyBlock->id());

        // Clone each of the instructions in the block.
        for (auto& origInst : *origBlock) {
            auto copyInst = unit.clone(&origInst);

            // Remember the new SSATmps (the dests) which will need to be renamed.
            for (size_t d = 0; d < origInst.numDsts(); d++) {
                tmpRenames[origInst.dst(d)] = copyInst->dst(d);
            }

            // Rename all the source SSATmps that need renaming.
            for (size_t s = 0; s < origInst.numSrcs(); s++) {
                auto it = tmpRenames.find(copyInst->src(s));
                if (it != tmpRenames.end()) {
                    auto newSrc = it->second;
                    copyInst->setSrc(s, newSrc);
                }
            }
            copyBlock->push_back(copyInst);
        }

        push(origBlock->next());
        push(origBlock->taken());
    }

    // Now go through all new blocks and reset their next/taken blocks
    // to their corresponding new blocks.
    for (auto& blockRename : blockRenames) {
        auto newBlock = blockRename.second;
        auto& lastInst = newBlock->back();
        if (lastInst.next())  lastInst.setNext (blockRenames[lastInst.next()]);
        if (lastInst.taken()) lastInst.setTaken(blockRenames[lastInst.taken()]);
    }

    return blockRenames[startBlock];
}
Ejemplo n.º 7
0
	vector<int> Recoloring::MatchGaussians(CvEM& source_model, CvEM& target_model) {
		int num_g = source_model.get_nclusters();
		Mat sMu(source_model.get_means());
		Mat tMu(target_model.get_means());
		const CvMat** target_covs = target_model.get_covs();
		const CvMat** source_covs = source_model.get_covs();

		double best_dist = std::numeric_limits<double>::max();
		vector<int> best_res(num_g);
		vector<int> prmt(num_g); 

		for(int itr = 0; itr < 10; itr++) {
			for(int i=0;i<num_g;i++) prmt[i] = i;	//make a permutation
			randShuffle(Mat(prmt));

			//Greedy selection
			vector<int> res(num_g);
			vector<bool> taken(num_g);
			for(int sg = 0; sg < num_g; sg++) {
				double min_dist = std::numeric_limits<double>::max(); 
				int minv = -1;
				for(int tg = 0; tg < num_g; tg++) {
					if(taken[tg]) continue;

					//TODO: can save on re-calculation of pairs - calculate affinity matrix ahead
					//double d = norm(sMu(Range(prmt[sg],prmt[sg]+1),Range(0,3)),	tMu(Range(tg,tg+1),Range(0,3)));
					
					//symmetric kullback-leibler
					Mat diff = Mat(sMu(Range(prmt[sg],prmt[sg]+1),Range(0,3)) - tMu(Range(tg,tg+1),Range(0,3)));
					Mat d = diff * Mat(Mat(source_covs[prmt[sg]]).inv() + Mat(target_covs[tg]).inv()) * diff.t();
					Scalar tr = trace(Mat(
						Mat(Mat(source_covs[prmt[sg]])*Mat(target_covs[tg])) + 
						Mat(Mat(target_covs[tg])*Mat(source_covs[prmt[sg]]).inv()) + 
						Mat(Mat::eye(3,3,CV_64FC1)*2)
						));
					double kl_dist = ((double*)d.data)[0] + tr[0];
					if(kl_dist<min_dist) {
						min_dist = kl_dist;
						minv = tg;
					}
				}
				res[prmt[sg]] = minv;
				taken[minv] = true;
			}

			double dist = 0;
			for(int i=0;i<num_g;i++) {
				dist += norm(sMu(Range(prmt[i],prmt[i]+1),Range(0,3)),
							tMu(Range(res[prmt[i]],res[prmt[i]]+1),Range(0,3)));
			}
			if(dist < best_dist) {
				best_dist = dist;
				best_res = res;
			}
		}

		return best_res;
	}
Ejemplo n.º 8
0
	void processResData_ByChis( const std::string& resName, ContainerType& data, RotamerLibrary& _RotLib )
	{
		const double tollerance = 12.0;

		// Ensure full chi arrays
		size_t largestSoFar = data[0].chis.size();
		for( size_t i = 1; i < data.size(); i++ )
		{
			if( data[i].chis.size() > largestSoFar )
			{
				largestSoFar = data[i].chis.size();
				i = 0; // reset
			}
			while( data[i].chis.size() < largestSoFar )
			{
				data[i].chis.push_back(0.0);
			}
		}

		size_t done = 0;
		std::vector<bool> taken(data.size());
		while( data.size() > done )
		{
			ContainerType subdata;
			bool on = false;
			for( int i = (int)data.size()-1; i >= 0; i-- )
			{
				if( taken[i] != true && (!on || equalChis( subdata[0], data[i], tollerance ) ) )
				{
					subdata.push_back( data[i] );
					taken[i] = true;
					on = true;
					done++;
				}
			}
			processData( resName, subdata, _RotLib, tollerance );
			subdata.clear();
		}
		data.clear();
	}
Ejemplo n.º 9
0
Block* findDefiningBlock(const SSATmp* t, const IdomVector& idoms) {
  assertx(!t->inst()->is(DefConst));
  auto const srcInst = t->inst();

  if (srcInst->hasEdges()) {
    auto const next = srcInst->next();
    UNUSED auto const taken = srcInst->taken();
    always_assert_flog(
      next && taken,
      "hasEdges instruction defining a dst had no edges:\n  {}\n",
      srcInst->toString()
    );
    for (const auto& arc : next->preds()) {
      auto pred = arc.from();
      if (pred != srcInst->block() && !dominates(next, pred, idoms)) {
        return nullptr;
      }
    }
    return next;
  }

  return srcInst->block();
}
Ejemplo n.º 10
0
static void
permuteToOther(const PHX::MDField<Scalar,Cell,IP,Dim>& coords,
               const PHX::MDField<Scalar,Cell,IP,Dim>& other_coords,
               std::vector<typename ArrayTraits<Scalar,PHX::MDField<Scalar> >::size_type>& permutation)
{
    typedef typename ArrayTraits<Scalar,PHX::MDField<Scalar> >::size_type size_type;
    // We can safely assume: (1) The permutation is the same for every cell in
    // the workset. (2) The first workset has valid data. Hence we operate only
    // on cell 0.
    const size_type cell = 0;
    const size_type num_ip = coords.dimension(1), num_dim = coords.dimension(2);
    permutation.resize(num_ip);
    std::vector<char> taken(num_ip, 0);
    for (size_type ip = 0; ip < num_ip; ++ip) {
        // Find an other point to associate with ip.
        size_type i_min = 0;
        Scalar d_min = -1;
        for (size_type other_ip = 0; other_ip < num_ip; ++other_ip) {
            // For speed, skip other points that are already associated.
            if (taken[other_ip]) continue;
            // Compute the distance between the two points.
            Scalar d(0);
            for (size_type dim = 0; dim < num_dim; ++dim) {
                const Scalar diff = coords(cell, ip, dim) - other_coords(cell, other_ip, dim);
                d += diff*diff;
            }
            if (d_min < 0 || d < d_min) {
                d_min = d;
                i_min = other_ip;
            }
        }
        // Record the match.
        permutation[ip] = i_min;
        // This point is now taken.
        taken[i_min] = 1;
    }
}
Ejemplo n.º 11
0
void JumpData::print_data_on(outputStream* st) {
  print_shared(st, "JumpData");
  st->print_cr("taken(%u) displacement(%d)", taken(), displacement());
}
Ejemplo n.º 12
0
bool Block::isExit() const {
  return !taken() && !next();
}
Ejemplo n.º 13
0
    int ostreambuf::flush(flush_kind f, const char *appendbuf, int appendsize) {
        LOG("bz::ostreambuf::flush(" << f << ")");
        std::streamsize in_s = taken();
        LOG("\tinput_size=" << in_s);

        //set up compression engine input feed
        int written;
        if (in_s > 0) {
            z_strm->next_in = pbase();
            z_strm->avail_in = in_s;
            written = in_s;
        } else if (appendsize > 0) {
            z_strm->next_in = (char*)appendbuf;
            z_strm->avail_in = appendsize;
            written = appendsize;
            appendsize = 0;
        } else {
            z_strm->next_in = pbase();
            z_strm->avail_in = 0;
            written = 0;
        }

        bool redo = false;

        do {
            int cret;
            redo = false;
            bool error = false;

            //reset output
            z_strm->next_out = out.buf;
            z_strm->avail_out = out.size;

            /*
             LOG("\tpre_deflate: [" << z_strm->next_in << "]\tavail_in=" << z_strm->avail_in <<
                    "\tavail_out=" << z_strm->avail_out);
            */

            cret = ::BZ2_bzCompress(z_strm, flush_macro(f));

            /*
             LOG("\tpost_deflate: [" << z_strm->next_in << "]\tavail_in=" << z_strm->avail_in <<
                    "\tavail_out=" << z_strm->avail_out << "\tcret=" << cret);
            */

            //error handling
            if (finish_sync == f) {
                if (BZ_STREAM_END == cret) {
                    redo = false;
                //XXX manual mentions BZ_FINISHING but this macro isn't defined anywhere in the source code of the library
                // so I use BZ_FINISH_OK but I'm not sure
                } else if (BZ_FINISH_OK == cret) {
                    redo = true;
                } else {
                    //serious error, throw exception
                    LOG("\terror in finish:" << cret);
                    error = true;
                }
            } else if (full_sync == f) {
                if (BZ_FLUSH_OK == cret) {
                    LOG("\tanother go at sync");
                    redo = true;
                } else if (BZ_RUN_OK == cret) {
                    LOG("\tsync ok");
                    redo = false;
                } else {
                    LOG("\terror in sync: " << cret);
                    error = true;
                }
            } else if (no_sync == f) {
                if (BZ_RUN_OK != cret) {
                    LOG("\terror compressing " << cret);
                    error = true;
                }
            } else {
                LOG("\tERROR: unknown flush mode " << flush_macro(f));
                throw general_error();
                error = true;
            }

            if (error) {
                raise_error(cret);
            }

            LOG("\twriting " << (out.size - z_strm->avail_out) << " bytes");

            const std::streamsize count = out.size - z_strm->avail_out;
            if (count > 0) {
                const std::streamsize wrote = _sb->sputn (out.buf, count);
                if (count != wrote) {
                    LOG("\terror writting, only wrote " << wrote << " but asked for " << count);
                    raise_error(BZ_IO_ERROR);
                }
            }

            if ((0 == z_strm->avail_out) && (0 != z_strm->avail_in)) {
                LOG("\tavail_out=0 => redo");
                redo = true;
            }

            if (!redo && appendbuf && appendsize > 0) {
                z_strm->next_in = (char*)appendbuf;
                z_strm->avail_in = appendsize;
                written += appendsize;
                appendsize = 0;
                redo = true;
            }
        } while (redo);
        assert (0 == z_strm->avail_in);

        //reset buffer
        setp(in.buf, in.buf + in.size);
        return written;
    }