コード例 #1
0
ファイル: DataFlowOpts.cpp プロジェクト: aheejin/binaryen
 // Replaces all uses of a node with another value. This both modifies
 // the DataFlow IR to make the other users point to this one, and
 // updates the underlying Binaryen IR as well.
 // This can be used to "replace" a node with itself, which makes sense
 // when the node contents have changed and so the users must be updated.
 void replaceAllUsesWith(DataFlow::Node* node, DataFlow::Node* with) {
   // Const nodes are trivial to replace, but other stuff is trickier -
   // in particular phis.
   assert(with->isConst()); // TODO
   // All the users should be worked on later, as we will update them.
   auto& users = nodeUsers.getUsers(node);
   for (auto* user : users) {
     // Add the user to the work left to do, as we are modifying it.
     workLeft.insert(user);
     // `with` is getting another user.
     nodeUsers.addUser(with, user);
     // Replacing in the DataFlow IR is simple - just replace it,
     // in all the indexes it appears.
     std::vector<Index> indexes;
     for (Index i = 0; i < user->values.size(); i++) {
       if (user->values[i] == node) {
         user->values[i] = with;
         indexes.push_back(i);
       }
     }
     assert(!indexes.empty());
     // Replacing in the Binaryen IR requires more care
     switch (user->type) {
       case DataFlow::Node::Type::Expr: {
         auto* expr = user->expr;
         for (auto index : indexes) {
           *(getIndexPointer(expr, index)) = graph.makeUse(with);
         }
         break;
       }
       case DataFlow::Node::Type::Phi: {
         // Nothing to do: a phi is not in the Binaryen IR.
         // If the entire phi can become a constant, that will be
         // propagated when we process that phi later.
         break;
       }
       case DataFlow::Node::Type::Cond: {
         // Nothing to do: a cond is not in the Binaryen IR.
         // If the cond input is a constant, that might indicate
         // useful optimizations are possible, which perhaps we
         // should look into TODO
         break;
       }
       case DataFlow::Node::Type::Zext: {
         // Nothing to do: a zext is not in the Binaryen IR.
         // If the cond input is a constant, that might indicate
         // useful optimizations are possible, which perhaps we
         // should look into TODO
         break;
       }
       default: WASM_UNREACHABLE();
     }
   }
   // No one is a user of this node after we replaced all the uses.
   nodeUsers.removeAllUsesOf(node);
 }
コード例 #2
0
ファイル: DataFlowOpts.cpp プロジェクト: aheejin/binaryen
 void optimizeExprToConstant(DataFlow::Node* node) {
   assert(node->isExpr());
   assert(!node->isConst());
   //std::cout << "will optimize an Expr of all constant inputs. before" << '\n';
   //dump(node, std::cout);
   auto* expr = node->expr;
   // First, note that some of the expression's children may be
   // local.gets that we inferred during SSA analysis as constant.
   // We can apply those now.
   for (Index i = 0; i < node->values.size(); i++) {
     if (node->values[i]->isConst()) {
       auto* currp = getIndexPointer(expr, i);
       // Directly represent it as a constant. (Note that it may already be
       // a constant, but for now to avoid corner cases just replace them
       // all here.)
       auto* c = node->values[i]->expr->dynCast<Const>();
       *currp = Builder(*getModule()).makeConst(c->value);
     }
   }
   // Now we know that all our DataFlow inputs are constant, and all
   // our Binaryen IR representations of them are constant too. RUn
   // precompute, which will transform the expression into a constanat.
   Module temp;
   // XXX we should copy expr here, in principle, and definitely will need to
   //     when we do arbitrarily regenerated expressions
   auto* func = Builder(temp).makeFunction("temp", std::vector<Type>{}, none, std::vector<Type>{}, expr);
   PassRunner runner(&temp);
   runner.setIsNested(true);
   runner.add("precompute");
   runner.runOnFunction(func);
   // Get the optimized thing
   auto* result = func->body;
   // It may not be a constant, e.g. 0 / 0 does not optimize to 0
   if (!result->is<Const>()) return;
   // All good, copy it.
   node->expr = Builder(*getModule()).makeConst(result->cast<Const>()->value);
   assert(node->isConst());
   // We no longer have values, and so do not use anything.
   nodeUsers.stopUsingValues(node);
   node->values.clear();
   // Our contents changed, update our users.
   replaceAllUsesWith(node, node);
 }
コード例 #3
0
ファイル: render.cpp プロジェクト: sgynn/worldeditor
//// Drawable functions ////
void DMesh::draw( RenderInfo& r) {
	glPushMatrix();
	glMultMatrixf(m_transform);
	// Material
	r.material( Drawable::m_material );
	r.state( 1 + (getNormalPointer()? 2:0) + (getTexCoordPointer()?4:0) );
	glVertexPointer(3, GL_FLOAT, getStride(), getVertexPointer());
	glNormalPointer(   GL_FLOAT, getStride(), getNormalPointer());
	glTexCoordPointer(2, GL_FLOAT, getStride(), getTexCoordPointer());
	// Tangents?
	if(getTangentPointer() && base::Shader::current().ready()) {
		base::Shader::current().AttributePointer("tangent", 3, GL_FLOAT, 0, getStride(), getTangentPointer());
	}
	// Draw it
	if(hasIndices()) glDrawElements( getMode(), getSize(), GL_UNSIGNED_SHORT, getIndexPointer());
	else glDrawArrays( getMode(), 0, getSize());

	glPopMatrix();
}