void guardt::add(const exprt &expr) { assert(expr.type().id()==ID_bool); if(is_false() || expr.is_true()) return; else if(is_true() || expr.is_false()) { *this=expr; return; } else if(id()!=ID_and) { and_exprt a; a.copy_to_operands(*this); *this=a; } operandst &op=operands(); if(expr.id()==ID_and) op.insert(op.end(), expr.operands().begin(), expr.operands().end()); else op.push_back(expr); }
void one(const char* fname, int flag=0, const char* apname = 0) { if (apname == 0) apname = fname; ofs << "/****************************************************************************" << std::endl << " * " << fname << std::endl << " ****************************************************************************/" << std::endl << std::endl; if (flag == ieeeflag) ofs << "#ifdef BZ_HAVE_IEEE_MATH" << std::endl; else if (flag == bsdflag) ofs << "#ifdef BZ_HAVE_SYSTEM_V_MATH" << std::endl; OperandTuple operands(1); do { if (operands.anyComplex()) ofs << "#ifdef BZ_HAVE_COMPLEX" << std::endl; operands.printTemplates(ofs); ofs << std::endl << "inline" << std::endl << "_bz_ArrayExpr<_bz_ArrayExprUnaryOp<"; operands.printIterators(ofs); ofs << "," << std::endl << " _bz_" << apname << "<"; operands[0].printNumtype(ofs); ofs << "> > >" << std::endl << fname << "("; operands.printArgumentList(ofs); ofs << ")" << std::endl << "{" << std::endl; ofs << " return _bz_ArrayExprUnaryOp<"; operands.printIterators(ofs); ofs << "," << std::endl << " _bz_" << apname << "<"; operands[0].printNumtype(ofs); ofs << "> >("; operands.printInitializationList(ofs); ofs << ");" << std::endl << "}" << std::endl; if (operands.anyComplex()) ofs << "#endif // BZ_HAVE_COMPLEX" << std::endl; ofs << std::endl; } while (++operands); if (flag != 0) ofs << "#endif" << std::endl; ofs << std::endl; }
extractbits_exprt::extractbits_exprt( const exprt &_src, const std::size_t _upper, const std::size_t _lower, const typet &_type): exprt(ID_extractbits, _type) { assert(_upper>=_lower); operands().resize(3); src()=_src; upper()=constant_exprt::integer_constant(_upper); lower()=constant_exprt::integer_constant(_lower); }
OOModel::UnfinishedOperator* CommandDescriptor::createUnfinished(const QString& name, const QList<OOModel::Expression*>& arguments) { auto unf = new OOModel::UnfinishedOperator(); unf->delimiters()->append(new Model::Text("\\")); unf->operands()->append(new OOModel::ReferenceExpression(name)); if (!arguments.isEmpty()) { unf->delimiters()->append(new Model::Text("(")); for(int i = 0; i< arguments.size(); ++i) { if (i > 0) unf->delimiters()->append(new Model::Text(",")); unf->operands()->append(arguments[i]); } unf->delimiters()->append(new Model::Text(")")); } else unf->delimiters()->append(new Model::Text(QString())); // append an empty postfix if there are no arguments return unf; }
void two(const char* fname, int flag=0, const char* apname = 0) { if (apname == 0) apname = fname; ofs << "/****************************************************************************" << std::endl << " * " << fname << std::endl << " ****************************************************************************/" << std::endl << std::endl; if (flag == ieeeflag) ofs << "#ifdef BZ_HAVE_IEEE_MATH" << std::endl; else if (flag == bsdflag) ofs << "#ifdef BZ_HAVE_SYSTEM_V_MATH" << std::endl; else if (flag == cmplxflag) ofs << "#ifdef BZ_HAVE_COMPLEX_FCNS" << std::endl; OperandTuple operands(2); do { operands.printTemplates(ofs); ofs << std::endl << "inline" << std::endl << "_bz_VecExpr<_bz_VecExprOp<"; operands.printIterators(ofs); ofs << "," << std::endl << " _bz_" << apname << "<"; operands[0].printNumtype(ofs); ofs << ","; operands[1].printNumtype(ofs); ofs << "> > >" << std::endl << fname << "("; operands.printArgumentList(ofs); ofs << ")" << std::endl << "{" << std::endl << " typedef _bz_VecExprOp<"; operands.printIterators(ofs); ofs << "," << std::endl << " _bz_" << apname << "<"; operands[0].printNumtype(ofs); ofs << ","; operands[1].printNumtype(ofs); ofs << "> > T_expr;" << std::endl << std::endl << " return _bz_VecExpr<T_expr>(T_expr("; operands.printInitializationList(ofs); ofs << "));" << std::endl << "}" << std::endl << std::endl; } while (++operands); if (flag != 0) ofs << "#endif" << std::endl; ofs << std::endl; }
std::shared_ptr<prediction_context> prediction_context_cache::get_child(std::shared_ptr<prediction_context> const& context, int return_state) { if (!private_data) { return prediction_context::get_child(context, return_state); } prediction_context_and_int operands(context, return_state); auto result = private_data->child_contexts.find(operands); if (result == private_data->child_contexts.end()) { auto child_context = get_as_cached(prediction_context::get_child(context, return_state)); result = private_data->child_contexts.insert(std::make_pair(std::move(operands), std::move(child_context))).first; } return result->second; }
ArgumentExtractor Frame::extract(bool evaluate) { Cell * args = NULL; if (evaluate) { args = unwrap(); } else { args = operands(); } // We don't need this as long as all arguments are optional.. otherwise, as expected, required arguments will cause an error. //if (args == NULL) { // throw Exception("No arguments provided!", this); // Dummy for extraction of null arguments. // args = new Cell(NULL, NULL); //} return args->extract(this); }
// With optimisations turned on, this function seems to cause stack frames to be reused and cause problems..!? Cell * Frame::unwrap() { #ifdef KAI_DEBUG std::cerr << "Unwrapping with frame: " << this << std::endl; #endif if (_arguments) return _arguments; Cell * last = NULL; Cell * cur = operands(); while (cur) { Ref<Object> value = NULL; // If cur->head() == NULL, the result is also NULL. if (cur->head()) value = cur->head()->evaluate(this); last = Cell::append(this, last, value, _arguments); cur = cur->tail().as<Cell>(); } return _arguments; }
object *eval(object *exp, object *env) { object *procedure; object *arguments; object *result; bool tailcall = false; do { if (is_self_evaluating(exp)) return exp; if (is_variable(exp)) return lookup_variable_value(exp, env); if (is_quoted(exp)) return text_of_quotation(exp); if (is_assignment(exp)) return eval_assignment(exp, env); if (is_definition(exp)) return eval_definition(exp, env); if (is_if(exp)) { exp = is_true(eval(if_predicate(exp), env)) ? if_consequent(exp) : if_alternative(exp); tailcall = true; continue; } if (is_lambda(exp)) return make_compound_proc(lambda_parameters(exp), lambda_body(exp), env); if (is_begin(exp)) { exp = begin_actions(exp); while (!is_last_exp(exp)) { eval(first_exp(exp), env); exp = rest_exps(exp); } exp = first_exp(exp); tailcall = true; continue; } if (is_cond(exp)) { exp = cond_to_if(exp); tailcall = true; continue; } if (is_let(exp)) { exp = let_to_application(exp); tailcall = true; continue; } if (is_and(exp)) { exp = and_tests(exp); if (is_empty(exp)) return make_boolean(true); while (!is_last_exp(exp)) { result = eval(first_exp(exp), env); if (is_false(result)) return result; exp = rest_exps(exp); } exp = first_exp(exp); tailcall = true; continue; } if (is_or(exp)) { exp = or_tests(exp); if (is_empty(exp)) { return make_boolean(false); } while (!is_last_exp(exp)) { result = eval(first_exp(exp), env); if (is_true(result)) return result; exp = rest_exps(exp); } exp = first_exp(exp); tailcall = true; continue; } if (is_application(exp)) { procedure = eval(operator(exp), env); arguments = list_of_values(operands(exp), env); if (is_primitive_proc(procedure) && procedure->data.primitive_proc.fn == eval_proc) { exp = eval_expression(arguments); env = eval_environment(arguments); tailcall = true; continue; } if (is_primitive_proc(procedure) && procedure->data.primitive_proc.fn == apply_proc) { procedure = apply_operator(arguments); arguments = apply_operands(arguments); } if (is_primitive_proc(procedure)) return (procedure->data.primitive_proc.fn)(arguments); if (is_compound_proc(procedure)) { env = extend_environment(procedure->data.compound_proc.parameters, arguments, procedure->data.compound_proc.env); exp = make_begin(procedure->data.compound_proc.body); tailcall = true; continue; } return make_error(342, "unknown procedure type"); } // is_application() } while (tailcall); fprintf(stderr, "cannot eval unknown expression type\n"); exit(EXIT_FAILURE); }
void OperandIterator::initIterator() { xmmsv_t *operands( xmmsv_coll_operands_get( coll_.coll_ ) ); xmmsv_get_list_iter( operands, &oper_it_ ); }
int main() { std::cout << "Generating <vecbfn.cc>" << std::endl; OperandTuple operands(2); bzofstream ofs("../vecbfn.cc", "Vector expression binary functions (2 operands)", __FILE__, "BZ_VECBFN_CC"); ofs << "#ifndef BZ_VECEXPR_H" << std::endl << " #error <blitz/vecbfn.cc> must be included via <blitz/vecexpr.h>" << std::endl << "#endif" << std::endl << std::endl; ofs.beginNamespace(); struct { const char* opSymbol; bool nonIntOperands; bool complexOperands; const char* opApplicName; const char* comment; } ops[] = { { "min", true, false, "_bz_Min", "Minimum Operators" }, { "max", true, false, "_bz_Max", "Maximum Operators" }, }; for (int i=0; i < 2; ++i) { ofs << "/****************************************************************************" << std::endl << " * " << ops[i].comment << std::endl << " ****************************************************************************/" << std::endl; operands.reset(); do { // Can't declare operator+(int,Range) or operator+(Range,int) // because these would conflict with the versions defined // in range.h. Also, the versions in range.h will be // much faster. if (operands[0].isScalar() && operands[0].isInteger() && operands[1].isRange()) continue; if (operands[1].isScalar() && operands[1].isInteger() && operands[0].isRange()) continue; if (ops[i].nonIntOperands == false) { if ((operands[0].isScalar() && !operands[0].isInteger()) || (operands[1].isScalar() && !operands[1].isInteger())) continue; } // Vector<P_numtype1> + _bz_VecExpr<P_expr2> if (operands.anyComplex()) ofs << "#ifdef BZ_HAVE_COMPLEX" << std::endl; ofs << std::endl << "// "; operands[0].printName(ofs); ofs << " " << ops[i].opSymbol << " "; operands[1].printName(ofs); ofs << std::endl; operands.printTemplates(ofs); ofs << std::endl << "inline" << std::endl; // _bz_VecExpr<_bz_VecExprOp<VectorIterConst<T_numtype1>, // _bz_VecExpr<T_expr2>, _bz_Add<T_numtype1,typename T_expr2::T_numtype> > > ofs << "_bz_VecExpr<_bz_VecExprOp<"; operands.printIterators(ofs, 1); ofs << "," << std::endl << " " << ops[i].opApplicName << "<"; operands[0].printNumtype(ofs); ofs << ", "; operands[1].printNumtype(ofs); ofs << " > > >" << std::endl; // operator+(const Vector<T_numtype1>& d1, _bz_VecExpr<T_expr2> d2) ofs << ops[i].opSymbol << "("; operands.printArgumentList(ofs, 1); ofs << ")" << std::endl << "{" << std::endl; // typedef _bz_VecExprOp<VectorIterConst<T_numtype1>, // _bz_VecExpr<T_expr2>, _bz_Add<T_numtype1,typename T_expr2::T_numtype> > T_expr; ofs << " typedef _bz_VecExprOp<"; operands.printIterators(ofs, 1); ofs << ", " << std::endl << " " << ops[i].opApplicName << "<"; operands[0].printNumtype(ofs); ofs << ", "; operands[1].printNumtype(ofs); ofs << "> > T_expr;" << std::endl << std::endl; // return _bz_VecExpr<T_expr>(T_expr(a.begin(), b)); ofs << " return _bz_VecExpr<T_expr>(T_expr("; operands.printInitializationList(ofs,1); ofs << "));" << std::endl << "}" << std::endl; if (operands.anyComplex()) ofs << "#endif // BZ_HAVE_COMPLEX" << std::endl << std::endl; } while (++operands); } std::cout << operands.numSpecializations() << " operators written." << std::endl; }
sExpression *eval(sExpression *exp, sEnvironment *env){ /* ------------------atom-----------------------*/ /* 1, 10, false, null, "abc" */ if(isSelfEval(exp)) { return exp; } /* a symbol */ else if(isVariable(exp, env)) { return lookupVariable(toSymb(exp), env); } /* ------------------list-----------------------*/ /* (quote blur blur) */ else if(isQuoted(exp)) { return textOfQuoted(exp); } /* (set! name value) */ else if(isAssignment(exp)) { return evalAssignment(exp, env); } /* (define name value) */ else if(isDefinition(exp)) { return evalDefine(exp, env); } /* (define-syntax name ...) */ else if(isDefinitionSyntax(exp)) { return evalDefineSyntax(exp, env); } /* (if blur blur blur) */ else if(isIf(exp)) { return evalIf(toList(exp), env); } /* (lambda (args) (body)) */ else if(isLambdaConst(exp)) { sList *body; sList *param = toList( cadr(toList(exp))); sExpression *temp = cdr(toList( cdr(toList(exp)))); if(isList(temp)){ body = toList(temp); }else{ body = toList(cons(temp, &sNull)); } return newLambda(param, body, env); } /* (syntax blur blur) syntax rule */ else if(isSymbol(car(toList(exp))) && isSyntaxRule(eval(car(toList(exp)), env))) { sExpression *exp2 = evalSyntaxRule(toSyntax(eval(car(toList(exp)), env)), exp); return eval(exp2, env); } /* the other list (x . y) */ else if(isApplication(exp)) { if(LAZY_EVAL){ sExpression *proexp = actualValue(operator(toList(exp)), env); if(isLambdaType(proexp) || isPrimitiveProc(proexp)){ sExpression *operand = operands(toList(exp)); return applyLazly(proexp, operand, env); } }else{ sExpression *proexp = eval(operator(toList(exp)), env); if(isLambdaType(proexp) || isPrimitiveProc(proexp)){ sExpression *operand = operands(toList(exp)); sExpression *arguments = listOfValues(operand, env); return apply(proexp, arguments, env); } } } return &sError; }
int main() { std::cout << "Generating <vecbops.cc>" << std::endl; OperandTuple operands(2); bzofstream ofs("../vecbops.cc", "Vector expression templates (2 operands)", __FILE__, "BZ_VECBOPS_CC"); ofs << "#ifndef BZ_VECEXPR_H" << std::endl << " #error <blitz/vecbops.cc> must be included via <blitz/vecexpr.h>" << std::endl << "#endif" << std::endl << std::endl; ofs.beginNamespace(); struct { const char* opSymbol; bool nonIntOperands; bool complexOperands; const char* opApplicName; const char* comment; } ops[] = { { "+", true, true, "_bz_Add", "Addition Operators" }, { "-", true, true, "_bz_Subtract", "Subtraction Operators" }, { "*", true, true, "_bz_Multiply", "Multiplication Operators" }, { "/", true, true, "_bz_Divide", "Division Operators" }, { "%", false, false, "_bz_Mod", "Modulus Operators" }, { "^", false, false, "_bz_BitwiseXOR", "Bitwise XOR Operators" }, { "&", false, false, "_bz_BitwiseAnd", "Bitwise And Operators" }, { "|", false, false, "_bz_BitwiseOr", "Bitwise Or Operators" }, { ">>", false, false, "_bz_ShiftRight", "Shift right Operators" }, { "<<", false, false, "_bz_ShiftLeft", "Shift left Operators" }, { ">", true, false, "_bz_Greater", "Greater-than Operators" }, { "<", true, false, "_bz_Less", "Less-than Operators" }, { ">=", true, false, "_bz_GreaterOrEqual", "Greater or equal (>=) operators" }, { "<=", true, false, "_bz_LessOrEqual", "Less or equal (<=) operators" }, { "==", true, true, "_bz_Equal", "Equality operators" }, { "!=", true, true, "_bz_NotEqual", "Not-equal operators" }, { "&&", false, false, "_bz_LogicalAnd", "Logical AND operators" }, { "||", false, false, "_bz_LogicalOr", "Logical OR operators" } }; for (int i=0; i < 18; ++i) { ofs << "/****************************************************************************" << std::endl << " * " << ops[i].comment << std::endl << " ****************************************************************************/" << std::endl; operands.reset(); do { // Can't declare operator+(int,Range) or operator+(Range,int) // because these would conflict with the versions defined // in range.h. Also, the versions in range.h will be // much faster. if (operands[0].isScalar() && operands[0].isInteger() && operands[1].isRange()) continue; if (operands[1].isScalar() && operands[1].isInteger() && operands[0].isRange()) continue; if (ops[i].nonIntOperands == false) { if ((operands[0].isScalar() && !operands[0].isInteger()) || (operands[1].isScalar() && !operands[1].isInteger())) continue; } // Vector<P_numtype1> + _bz_VecExpr<P_expr2> if (operands.anyComplex()) ofs << "#ifdef BZ_HAVE_COMPLEX" << std::endl; ofs << std::endl << "// "; operands[0].printName(ofs); ofs << " " << ops[i].opSymbol << " "; operands[1].printName(ofs); ofs << std::endl; operands.printTemplates(ofs); ofs << std::endl << "inline" << std::endl; // _bz_VecExpr<_bz_VecExprOp<VectorIterConst<T_numtype1>, // _bz_VecExpr<T_expr2>, _bz_Add<T_numtype1,typename T_expr2::T_numtype> > > ofs << "_bz_VecExpr<_bz_VecExprOp<"; operands.printIterators(ofs, 1); ofs << "," << std::endl << " " << ops[i].opApplicName << "<"; operands[0].printNumtype(ofs); ofs << ", "; operands[1].printNumtype(ofs); ofs << " > > >" << std::endl; // operator+(const Vector<T_numtype1>& d1, _bz_VecExpr<T_expr2> d2) if (ops[i].opSymbol[0] == 'm') ofs << ops[i].opSymbol << "("; else ofs << "operator" << ops[i].opSymbol << "("; operands.printArgumentList(ofs, 1); ofs << ")" << std::endl << "{" << std::endl; // typedef _bz_VecExprOp<VectorIterConst<T_numtype1>, // _bz_VecExpr<T_expr2>, _bz_Add<T_numtype1,typename T_expr2::T_numtype> > T_expr; ofs << " typedef _bz_VecExprOp<"; operands.printIterators(ofs, 1); ofs << ", " << std::endl << " " << ops[i].opApplicName << "<"; operands[0].printNumtype(ofs); ofs << ", "; operands[1].printNumtype(ofs); ofs << "> > T_expr;" << std::endl << std::endl; // return _bz_VecExpr<T_expr>(T_expr(a.begin(), b)); ofs << " return _bz_VecExpr<T_expr>(T_expr("; operands.printInitializationList(ofs,1); ofs << "));" << std::endl << "}" << std::endl; if (operands.anyComplex()) ofs << "#endif // BZ_HAVE_COMPLEX" << std::endl << std::endl; } while (++operands); } std::cout << operands.numSpecializations() << " operators written." << std::endl; }
static pSlipObject slip_eval(pSlip gd, pSlipObject exp, pSlipEnvironment env) { pSlipObject proc; pSlipObject args; tailcall: if (is_self_evaluating(exp) == S_TRUE) { return exp; } else if (is_variable(exp) == S_TRUE) { return lookup_variable_value(gd, exp, env); } else if (is_quoted(gd, exp) == S_TRUE) { return text_of_quotation(exp); } else if (is_assignment(gd, exp) == S_TRUE) { return eval_assignment(gd, exp, env); } else if (is_definition(gd, exp) == S_TRUE) { return eval_definition(gd, exp, env); } else if (is_if(gd, exp) == S_TRUE) { exp = is_true(gd, slip_eval(gd, if_predicate(exp), env)) == S_TRUE ? if_consequent(exp) : if_alternative(gd, exp); goto tailcall; } else if (is_lambda(gd, exp) == S_TRUE) { return s_NewCompoundProc(gd, lambda_parameters(exp), lambda_body(exp), env); } else if (is_begin(gd, exp) == S_TRUE) { exp = begin_actions(exp); while (!is_last_exp(gd, exp)) { slip_eval(gd, first_exp(exp), env); exp = rest_exps(exp); } exp = first_exp(exp); goto tailcall; } else if (is_cond(gd, exp) == S_TRUE) { exp = cond_to_if(gd, exp); goto tailcall; } else if (is_let(gd, exp) == S_TRUE) { exp = let_to_application(gd, exp); goto tailcall; } else if (is_application(exp) == S_TRUE) { proc = slip_eval(gd, slip_operator(exp), env); if (proc == NULL) return gd->singleton_False; if (proc->type == eType_PRIMITIVE_PROC || proc->type == eType_COMPOUND_PROC) { args = list_of_values(gd, operands(exp), env); if (args == NULL) return gd->singleton_False; if (sIsObject_PrimitiveProc(proc) == S_TRUE) { return proc->data.prim_proc.func(gd, args); } else if (sIsObject_CompoundProc(proc) == S_TRUE) { env = setup_environment(gd, proc->data.comp_proc.env, proc->data.comp_proc.params, args); exp = make_begin(gd, proc->data.comp_proc.code); goto tailcall; } else { throw_error(gd, "unknown procedure type\n"); return gd->singleton_False; } } else return proc; } else { throw_error(gd, "cannot eval unknown expression type\n"); return NULL; } throw_error(gd, "what??\n"); return NULL; }
bool Sink(MIRGenerator* mir, MIRGraph& graph) { TempAllocator& alloc = graph.alloc(); bool sinkEnabled = mir->optimizationInfo().sinkEnabled(); for (PostorderIterator block = graph.poBegin(); block != graph.poEnd(); block++) { if (mir->shouldCancel("Sink")) return false; for (MInstructionReverseIterator iter = block->rbegin(); iter != block->rend(); ) { MInstruction* ins = *iter++; // Only instructions which can be recovered on bailout can be moved // into the bailout paths. if (ins->isGuard() || ins->isGuardRangeBailouts() || ins->isRecoveredOnBailout() || !ins->canRecoverOnBailout()) { continue; } // Compute a common dominator for all uses of the current // instruction. bool hasLiveUses = false; bool hasUses = false; MBasicBlock* usesDominator = nullptr; for (MUseIterator i(ins->usesBegin()), e(ins->usesEnd()); i != e; i++) { hasUses = true; MNode* consumerNode = (*i)->consumer(); if (consumerNode->isResumePoint()) continue; MDefinition* consumer = consumerNode->toDefinition(); if (consumer->isRecoveredOnBailout()) continue; hasLiveUses = true; // If the instruction is a Phi, then we should dominate the // predecessor from which the value is coming from. MBasicBlock* consumerBlock = consumer->block(); if (consumer->isPhi()) consumerBlock = consumerBlock->getPredecessor(consumer->indexOf(*i)); usesDominator = CommonDominator(usesDominator, consumerBlock); if (usesDominator == *block) break; } // Leave this instruction for DCE. if (!hasUses) continue; // We have no uses, so sink this instruction in all the bailout // paths. if (!hasLiveUses) { MOZ_ASSERT(!usesDominator); ins->setRecoveredOnBailout(); JitSpewDef(JitSpew_Sink, " No live uses, recover the instruction on bailout\n", ins); continue; } // This guard is temporarly moved here as the above code deals with // Dead Code elimination, which got moved into this Sink phase, as // the Dead Code elimination used to move instructions with no-live // uses to the bailout path. if (!sinkEnabled) continue; // To move an effectful instruction, we would have to verify that the // side-effect is not observed. In the mean time, we just inhibit // this optimization on effectful instructions. if (ins->isEffectful()) continue; // If all the uses are under a loop, we might not want to work // against LICM by moving everything back into the loop, but if the // loop is it-self inside an if, then we still want to move the // computation under this if statement. while (block->loopDepth() < usesDominator->loopDepth()) { MOZ_ASSERT(usesDominator != usesDominator->immediateDominator()); usesDominator = usesDominator->immediateDominator(); } // Only move instructions if there is a branch between the dominator // of the uses and the original instruction. This prevent moving the // computation of the arguments into an inline function if there is // no major win. MBasicBlock* lastJoin = usesDominator; while (*block != lastJoin && lastJoin->numPredecessors() == 1) { MOZ_ASSERT(lastJoin != lastJoin->immediateDominator()); MBasicBlock* next = lastJoin->immediateDominator(); if (next->numSuccessors() > 1) break; lastJoin = next; } if (*block == lastJoin) continue; // Skip to the next instruction if we cannot find a common dominator // for all the uses of this instruction, or if the common dominator // correspond to the block of the current instruction. if (!usesDominator || usesDominator == *block) continue; // Only instruction which can be recovered on bailout and which are // sinkable can be moved into blocks which are below while filling // the resume points with a clone which is recovered on bailout. // If the instruction has live uses and if it is clonable, then we // can clone the instruction for all non-dominated uses and move the // instruction into the block which is dominating all live uses. if (!ins->canClone()) continue; // If the block is a split-edge block, which is created for folding // test conditions, then the block has no resume point and has // multiple predecessors. In such case, we cannot safely move // bailing instruction to these blocks as we have no way to bailout. if (!usesDominator->entryResumePoint() && usesDominator->numPredecessors() != 1) continue; JitSpewDef(JitSpew_Sink, " Can Clone & Recover, sink instruction\n", ins); JitSpew(JitSpew_Sink, " into Block %u", usesDominator->id()); // Copy the arguments and clone the instruction. MDefinitionVector operands(alloc); for (size_t i = 0, end = ins->numOperands(); i < end; i++) { if (!operands.append(ins->getOperand(i))) return false; } MInstruction* clone = ins->clone(alloc, operands); ins->block()->insertBefore(ins, clone); clone->setRecoveredOnBailout(); // We should not update the producer of the entry resume point, as // it cannot refer to any instruction within the basic block excepts // for Phi nodes. MResumePoint* entry = usesDominator->entryResumePoint(); // Replace the instruction by its clone in all the resume points / // recovered-on-bailout instructions which are not in blocks which // are dominated by the usesDominator block. for (MUseIterator i(ins->usesBegin()), e(ins->usesEnd()); i != e; ) { MUse* use = *i++; MNode* consumer = use->consumer(); // If the consumer is a Phi, then we look for the index of the // use to find the corresponding predecessor block, which is // then used as the consumer block. MBasicBlock* consumerBlock = consumer->block(); if (consumer->isDefinition() && consumer->toDefinition()->isPhi()) { consumerBlock = consumerBlock->getPredecessor( consumer->toDefinition()->toPhi()->indexOf(use)); } // Keep the current instruction for all dominated uses, except // for the entry resume point of the block in which the // instruction would be moved into. if (usesDominator->dominates(consumerBlock) && (!consumer->isResumePoint() || consumer->toResumePoint() != entry)) { continue; } use->replaceProducer(clone); } // As we move this instruction in a different block, we should // verify that we do not carry over a resume point which would refer // to an outdated state of the control flow. if (ins->resumePoint()) ins->clearResumePoint(); // Now, that all uses which are not dominated by usesDominator are // using the cloned instruction, we can safely move the instruction // into the usesDominator block. MInstruction* at = usesDominator->safeInsertTop(nullptr, MBasicBlock::IgnoreRecover); block->moveBefore(at, ins); } } return true; }
int main() { std::cout << "Generating <matbops.h>" << std::endl; OperandTuple2 operands(2); std::ofstream ofs("../matbops.h"); ofs << "// Generated source file. Do not edit." << std::endl; ofs << "// Created by: " << __FILE__ << " " << __DATE__ << " " << __TIME__ << std::endl << std::endl; ofs << "#ifndef BZ_MATBOPS_H" << std::endl << "#define BZ_MATBOPS_H" << std::endl << std::endl << "BZ_NAMESPACE(blitz)" << std::endl << std::endl << "#ifndef BZ_MATEXPR_H" << std::endl << " #error <blitz/matbops.h> must be included via <blitz/matexpr.h>" << std::endl << "#endif" << std::endl << std::endl; struct { const char* opSymbol; bool nonIntOperands; bool complexOperands; const char* opApplicName; const char* comment; } ops[] = { { "+", true, true, "_bz_Add", "Addition Operators" }, { "-", true, true, "_bz_Subtract", "Subtraction Operators" }, { "*", true, true, "_bz_Multiply", "Multiplication Operators" }, { "/", true, true, "_bz_Divide", "Division Operators" }, { "%", false, false, "_bz_Mod", "Modulus Operators" }, { "^", false, false, "_bz_BitwiseXOR", "Bitwise XOR Operators" }, { "&", false, false, "_bz_BitwiseAnd", "Bitwise And Operators" }, { "|", false, false, "_bz_BitwiseOr", "Bitwise Or Operators" }, { ">>", false, false, "_bz_ShiftRight", "Shift right Operators" }, { "<<", false, false, "_bz_ShiftLeft", "Shift left Operators" }, { ">", true, false, "_bz_Greater", "Greater-than Operators" }, { "<", true, false, "_bz_Less", "Less-than Operators" }, { ">=", true, false, "_bz_GreaterOrEqual", "Greater or equal (>=) operators" }, { "<=", true, false, "_bz_LessOrEqual", "Less or equal (<=) operators" }, { "==", true, true, "_bz_Equal", "Equality operators" }, { "!=", true, true, "_bz_NotEqual", "Not-equal operators" }, { "&&", false, false, "_bz_LogicalAnd", "Logical AND operators" }, { "||", false, false, "_bz_LogicalOr", "Logical OR operators" }, { "min", false, false, "_bz_Min", "Minimum Operators" }, { "max", false, false, "_bz_Max", "Maximum Operators" } }; for (int i=0; i < 20; ++i) { ofs << "/****************************************************************************" << std::endl << " * " << ops[i].comment << std::endl << " ****************************************************************************/" << std::endl; operands.reset(); do { if (ops[i].nonIntOperands == false) { if ((operands[0].isScalar() && !operands[0].isInteger()) || (operands[1].isScalar() && !operands[1].isInteger())) continue; } // Matrix<P_numtype1> + _bz_MatExpr<P_expr2> if (operands.anyComplex()) ofs << "#ifdef BZ_HAVE_COMPLEX" << std::endl; ofs << std::endl << "// "; operands[0].printName(ofs); ofs << " " << ops[i].opSymbol << " "; operands[1].printName(ofs); ofs << std::endl; operands.printTemplates(ofs); ofs << std::endl << "inline" << std::endl; // _bz_MatExpr<_bz_MatExprOp<MatRef<T_numtype1>, // _bz_MatExpr<T_expr2>, _bz_Add<T_numtype1,typename T_expr2::T_numtype> > > ofs << "_bz_MatExpr<_bz_MatExprOp<"; operands.printIterators(ofs, 1); ofs << "," << std::endl << " " << ops[i].opApplicName << "<"; operands[0].printNumtype(ofs); ofs << ", "; operands[1].printNumtype(ofs); ofs << " > > >" << std::endl; // operator+(const Matrix<T_numtype1>& d1, _bz_MatExpr<T_expr2> d2) if (ops[i].opSymbol[0] == 'm') ofs << "(" << ops[i].opSymbol << ")("; else ofs << "operator" << ops[i].opSymbol << "("; operands.printArgumentList(ofs, 1); ofs << ")" << std::endl << "{" << std::endl; // typedef _bz_MatExprOp<MatRef<T_numtype1>, // _bz_MatExpr<T_expr2>, _bz_Add<T_numtype1,typename T_expr2::T_numtype> > T_expr; ofs << " typedef _bz_MatExprOp<"; operands.printIterators(ofs, 1); ofs << ", " << std::endl << " " << ops[i].opApplicName << "<"; operands[0].printNumtype(ofs); ofs << ", "; operands[1].printNumtype(ofs); ofs << "> > T_expr;" << std::endl << std::endl; // return _bz_MatExpr<T_expr>(T_expr(a.begin(), b)); ofs << " return _bz_MatExpr<T_expr>(T_expr("; operands.printInitializationList(ofs,1); ofs << "));" << std::endl << "}" << std::endl; if (operands.anyComplex()) ofs << "#endif // BZ_HAVE_COMPLEX" << std::endl << std::endl; } while (++operands); } ofs << std::endl << "BZ_NAMESPACE_END" << std::endl << std::endl << "#endif // BZ_MATBOPS_H" << std::endl; std::cout << operands.numSpecializations() << " operators written." << std::endl; }
inline Operand Inst::operand(int index) { return operands()[index]; }
/////////////////////////////////////////////////////////////////// //eval //requires two arguments:exp & tail_context /////////////////////////////////////////////////////////////////// cellpoint eval(void) { if (is_true(is_self_evaluating(args_ref(1)))){ reg = args_ref(1); }else if (is_true(is_variable(args_ref(1)))){ reg = args_ref(1); args_push(current_env); args_push(reg); reg = lookup_var_val(); }else if (is_true(is_quoted(args_ref(1)))){ args_push(args_ref(1)); reg = quotation_text(); }else if (is_true(is_assignment(args_ref(1)))){ args_push(args_ref(1)); reg = eval_assignment(); }else if (is_true(is_definition(args_ref(1)))){ args_push(args_ref(1)); reg = eval_definition(); }else if (is_true(is_if(args_ref(1)))){ //eval if expression with the second argument (tail_context) reg = args_ref(1); args_push(args_ref(2)); args_push(reg); reg = eval_if(); }else if (is_true(is_lambda(args_ref(1)))){ args_push(args_ref(1)); reg = eval_lambda(); }else if (is_true(is_begin(args_ref(1)))){ args_push(args_ref(1)); reg = begin_actions(); //eval the actions of begin exp with the second argument (tail_context) args_push(args_ref(2)); args_push(reg); reg = eval_sequence(); }else if (is_true(is_cond(args_ref(1)))){ args_push(args_ref(1)); reg = cond_2_if(); //eval the exp with the second argument (tail_context) args_push(args_ref(2)); args_push(reg); reg = eval(); }else if (is_true(is_and(args_ref(1)))){ reg = args_ref(1); args_push(args_ref(2)); args_push(reg); reg = eval_and(); }else if (is_true(is_or(args_ref(1)))){ reg = args_ref(1); args_push(args_ref(2)); args_push(reg); reg = eval_or(); }else if (is_true(is_let(args_ref(1)))){ //convert let to combination args_push(args_ref(1)); reg = let_2_combination(); //evals the combination args_push(args_ref(2)); args_push(reg); reg = eval(); }else if (is_true(is_letstar(args_ref(1)))){ //convert let* to nested lets args_push(args_ref(1)); reg = letstar_2_nested_lets(); //evals the nested lets args_push(args_ref(2)); args_push(reg); reg = eval(); }else if (is_true(is_application(args_ref(1)))){ //computes operator args_push(args_ref(1)); reg = operator(); args_push(a_false); args_push(reg); reg = eval(); stack_push(&vars_stack, reg); //computes operands args_push(args_ref(1)); reg = operands(); args_push(reg); reg = list_of_values(); //calls apply with the second argument (tail_context) args_push(args_ref(2)); args_push(reg); args_push(stack_pop(&vars_stack)); reg = apply(); }else { printf("Unknown expression type -- EVAL\n"); error_handler(); } args_pop(2); return reg; }