void FakeDirectiveHandler::InsertAccess(Expr * Current,
                                    DeclRefExpr * Original,
                                    bool Write,
                                    vector<LocalStmtPair> WritePairs,
                                    bool ActualVar,
                                    string Struct) {

  if (!ActualVar) return;
  
  const Type * T = Current->getType().getTypePtr();
  
  if (FullDirectives->IsPrivate(Original, Struct, T, Original->getLocStart())) {
    return;
  }

  vector<LocalStmtPair>::iterator it;

  CompilerInstance &CI = FullDirectives->GetCI(Current->getLocStart());

  for (it = WritePairs.begin(); it != WritePairs.end(); it++) {
  
    bool insertAfter = it->insertAfter;
    Stmt * curStmt = it->stmt;

    bool isBracket = false;

    SourceLocation start = curStmt->getLocStart();
    SourceLocation end = FindSemiAfterLocation(curStmt->getLocEnd(),
                                               CI.getASTContext());

    if (end.isInvalid()) {
      end = curStmt->getLocEnd();
      isBracket = true;
    }
    
    SourceLocation loc;
    
    if (insertAfter) {
      if (isBracket) {
        loc = end;
      } else {
        loc = end.getLocWithOffset(1);
      }
    } else {
      loc = start;
    }
    
    loc = tools::UnpackMacroLoc(loc, CI);

    if (GetOrSetAccessed(loc, Current, Write)) {
      continue;
    }

    FullDirectives->InsertDeclAccess(Original->getFoundDecl(), Write);

  }

}
/// VerifyJumps - Verify each element of the Jumps array to see if they are
/// valid, emitting diagnostics if not.
void JumpScopeChecker::VerifyJumps() {
  while (!Jumps.empty()) {
    Stmt *Jump = Jumps.pop_back_val();

    // With a goto,
    if (GotoStmt *GS = dyn_cast<GotoStmt>(Jump)) {
      CheckJump(GS, GS->getLabel(), GS->getGotoLoc(),
                diag::err_goto_into_protected_scope);
      continue;
    }

    if (SwitchStmt *SS = dyn_cast<SwitchStmt>(Jump)) {
      for (SwitchCase *SC = SS->getSwitchCaseList(); SC;
           SC = SC->getNextSwitchCase()) {
        assert(LabelAndGotoScopes.count(SC) && "Case not visited?");
        CheckJump(SS, SC, SC->getLocStart(),
                  diag::err_switch_into_protected_scope);
      }
      continue;
    }

    unsigned DiagnosticScope;

    // We don't know where an indirect goto goes, require that it be at the
    // top level of scoping.
    if (IndirectGotoStmt *IG = dyn_cast<IndirectGotoStmt>(Jump)) {
      assert(LabelAndGotoScopes.count(Jump) &&
             "Jump didn't get added to scopes?");
      unsigned GotoScope = LabelAndGotoScopes[IG];
      if (GotoScope == 0) continue;  // indirect jump is ok.
      S.Diag(IG->getGotoLoc(), diag::err_indirect_goto_in_protected_scope);
      DiagnosticScope = GotoScope;
    } else {
      // We model &&Label as a jump for purposes of scope tracking.  We actually
      // don't care *where* the address of label is, but we require the *label
      // itself* to be in scope 0.  If it is nested inside of a VLA scope, then
      // it is possible for an indirect goto to illegally enter the VLA scope by
      // indirectly jumping to the label.
      assert(isa<AddrLabelExpr>(Jump) && "Unknown jump type");
      LabelStmt *TheLabel = cast<AddrLabelExpr>(Jump)->getLabel();

      assert(LabelAndGotoScopes.count(TheLabel) &&
             "Referenced label didn't get added to scopes?");
      unsigned LabelScope = LabelAndGotoScopes[TheLabel];
      if (LabelScope == 0) continue; // Addr of label is ok.

      S.Diag(Jump->getLocStart(), diag::err_addr_of_label_in_protected_scope);
      DiagnosticScope = LabelScope;
    }

    // Report all the things that would be skipped over by this &&label or
    // indirect goto.
    while (DiagnosticScope != 0) {
      S.Diag(Scopes[DiagnosticScope].Loc, Scopes[DiagnosticScope].Diag);
      DiagnosticScope = Scopes[DiagnosticScope].ParentScope;
    }
  }
}
Example #3
0
Stmt IRMutator2::visit(const LetStmt *op) {
    Expr value = mutate(op->value);
    Stmt body = mutate(op->body);
    if (value.same_as(op->value) &&
        body.same_as(op->body)) {
        return op;
    }
    return LetStmt::make(op->name, std::move(value), std::move(body));
}
bool uses_branches(Func f) {
    Target t = get_jit_target_from_environment();
    t.set_feature(Target::NoBoundsQuery);
    t.set_feature(Target::NoAsserts);
    Stmt s = Internal::lower(f.function(), t);
    ContainsBranches b;
    s.accept(&b);
    return b.result;
}
Example #5
0
int count_host_alignment_asserts(Func f, std::map<string, int> m) {
    Target t = get_jit_target_from_environment();
    t.set_feature(Target::NoBoundsQuery);
    f.compute_root();
    Stmt s = Internal::lower({f.function()}, f.name(), t);
    CountHostAlignmentAsserts c(m);
    s.accept(&c);
    return c.count;
}
Example #6
0
Stmt IRMutator2::visit(const Block *op) {
    Stmt first = mutate(op->first);
    Stmt rest = mutate(op->rest);
    if (first.same_as(op->first) &&
        rest.same_as(op->rest)) {
        return op;
    }
    return Block::make(std::move(first), std::move(rest));
}
Example #7
0
Stmt IRMutator::mutate(Stmt s) {
    if (s.defined()) {
        s.accept(this);
    } else {
        stmt = Stmt();
    }
    expr = Expr();
    return stmt;
}
Example #8
0
int count_interleaves(Func f) {
    Target t = get_jit_target_from_environment();
    t.set_feature(Target::NoBoundsQuery);
    t.set_feature(Target::NoAsserts);
    Stmt s = Internal::lower(f.function(), t);
    CountInterleaves i;
    s.accept(&i);
    return i.result;
}
  void NetworkDriverRewriteVisitor::InstrumentEntryPoints(FunctionDecl* funcDecl, string fdFile)
  {
    if (funcDecl->getStorageClass() == SC_Static)
      RW.RemoveText(funcDecl->getInnerLocStart(), 7);

    if (DI->getInstance().GetInitFunction() == funcDecl->getNameInfo().getName().getAsString())
      return;

    if (funcDecl->getParamDecl(0)->getOriginalType().getAsString() != "struct device *" &&
      funcDecl->getParamDecl(0)->getOriginalType().getAsString() != "struct pci_dev *")
      return;

    SourceRange sr = funcDecl->getParamDecl(0)->getSourceRange();

    RW.InsertTextBefore(sr.getBegin(), "struct net_device *dev, ");

    Stmt *body = funcDecl->getBody();
    list<DeclStmt*> stmtsToRewrite;

    for (auto i = body->child_begin(), e = body->child_end(); i != e; ++i)
    {
      if (!isa<DeclStmt>(*i))
        continue;

      DeclStmt *declStmt = cast<DeclStmt>(*i);
      if (!declStmt->isSingleDecl() && !isa<VarDecl>(declStmt->getSingleDecl()))
        continue;

      VarDecl *var = cast<VarDecl>(declStmt->getSingleDecl());
      if (!var->hasInit())
        continue;

      Expr *expr = var->getInit();
      if (!isa<ImplicitCastExpr>(expr))
        continue;

      ImplicitCastExpr *implicit = cast<ImplicitCastExpr>(expr);
      if (!isa<CallExpr>(implicit->getSubExpr()))
       continue;

      CallExpr *call = cast<CallExpr>(implicit->getSubExpr());
      DeclRefExpr *callee = cast<DeclRefExpr>(cast<ImplicitCastExpr>(call->getCallee())->getSubExpr());

      if (callee->getNameInfo().getName().getAsString() == "to_pci_dev" ||
          callee->getNameInfo().getName().getAsString() == "pci_get_drvdata")
      {
        stmtsToRewrite.push_back(declStmt);
      }
    }

    while (!stmtsToRewrite.empty())
    {
      DeclStmt *stmt = stmtsToRewrite.back();
      RW.RemoveText(stmt->getSourceRange());
      stmtsToRewrite.pop_back();
    }
  }
Example #10
0
bool ReserveCandidates::isInComplexLoop(clang::Stmt *s, SourceLocation declLocation, bool isMemberVariable) const
{
    if (!s || declLocation.isInvalid())
        return false;

    int forCount = 0;
    int foreachCount = 0;

    static vector<unsigned int> nonComplexOnesCache;
    static vector<unsigned int> complexOnesCache;
    auto rawLoc = s->getLocStart().getRawEncoding();


    // For some reason we generate two warnings on some foreaches, so cache the ones we processed
    // and return true so we don't trigger a warning
    if (clazy_std::contains(nonComplexOnesCache, rawLoc) || clazy_std::contains(complexOnesCache, rawLoc))
        return true;

    Stmt *parent = s;
    PresumedLoc lastForeachForStm;
    while ((parent = HierarchyUtils::parent(m_parentMap, parent))) {
        const SourceLocation parentStart = parent->getLocStart();
        if (!isMemberVariable && sm().isBeforeInSLocAddrSpace(parentStart, declLocation)) {
            nonComplexOnesCache.push_back(rawLoc);
            return false;
        }

        bool isLoop = false;
        if (loopIsComplex(parent, isLoop)) {
            complexOnesCache.push_back(rawLoc);
            return true;
        }

        if (QtUtils::isInForeach(m_ci, parentStart)) {
            auto ploc = sm().getPresumedLoc(parentStart);
            if (Utils::presumedLocationsEqual(ploc, lastForeachForStm)) {
                // Q_FOREACH comes in pairs, because each has two for statements inside, so ignore one when counting
            } else {
                foreachCount++;
                lastForeachForStm = ploc;
            }
        } else {
            if (isLoop)
                forCount++;
        }

        if (foreachCount > 1 || forCount > 1) { // two foreaches are almost always a false-positve
            complexOnesCache.push_back(rawLoc);
            return true;
        }


    }

    nonComplexOnesCache.push_back(rawLoc);
    return false;
}
Example #11
0
Stmt IRMutator::mutate(const Stmt &s) {
    if (s.defined()) {
        s.accept(this);
    } else {
        stmt = Stmt();
    }
    expr = Expr();
    return std::move(stmt);
}
Example #12
0
void IRMutator::visit(const LetStmt *op) {
    Expr value = mutate(op->value);
    Stmt body = mutate(op->body);
    if (value.same_as(op->value) &&
        body.same_as(op->body)) {
        stmt = op;
    } else {
        stmt = LetStmt::make(op->name, std::move(value), std::move(body));
    }
}
Example #13
0
void IRMutator::visit(const Block *op) {
    Stmt first = mutate(op->first);
    Stmt rest = mutate(op->rest);
    if (first.same_as(op->first) &&
        rest.same_as(op->rest)) {
        stmt = op;
    } else {
        stmt = Block::make(std::move(first), std::move(rest));
    }
}
Example #14
0
void print_vine_ir(asm_program_t *prog, vector<vine_block_t *> vblocks )
{
    unsigned int i, j;
    
    for ( i = 0; i < vblocks.size(); i++ )
    {
        vine_block_t *block = vblocks.at(i);
        assert(block);
        
        vector<Stmt *> *inner = block->vine_ir;

	//        cout << "Vine Block " << i << endl;
        cout << "  {" << endl;
// 	declvis vis;
// 	vis.compute(inner);
// 	print_decls(vis.decls);
	//        cout << "    ";
	ostringstream os;
	ostream_insn(prog, block->inst, os);
	cout << "   // " << os.str() << endl;


	vector<VarDecl *> globals = get_reg_decls();
	map<string,reg_t> context;
        for(vector<VarDecl *>::const_iterator gi = globals.begin();
	    gi != globals.end(); gi++){
           VarDecl *vd = *gi;
           context.insert(pair<string, reg_t>(vd->name, vd->typ));
        }

        for ( j = 0; j < inner->size(); j++ )
        {
#ifdef TYPECHECKING
	  try {
	  if (typecheck_stmt(&context,  inner->at(j)) < 0) {
	    cout <<"Type error found at:" <<endl;
	  }
	  } catch (TypeError &e) {
	    cout <<"Type Error: " << e.what() <<endl;
	    cout <<"Found at:" <<endl;
	  }
#endif
	  Stmt *s = inner->at(j);
	  cout << "     " << s->tostring();
// 	  if(s->stmt_type == LABEL)
// 	    cout << endl;
// 	  else
// 	    cout << ";" << endl;
	  cout << endl;

        }
        cout << "  }" << endl;
    }
    
}
Example #15
0
 void visit(const For *for_loop) {
     Stmt body = mutate(for_loop->body);
     const IntImm *extent = for_loop->extent.as<IntImm>();
     if (extent && extent->value == 1) {
         stmt = new LetStmt(for_loop->name, for_loop->min, body);
     } else if (body.same_as(for_loop->body)) {
         stmt = for_loop;
     } else {
         stmt = new For(for_loop->name, for_loop->min, for_loop->extent, for_loop->for_type, body);
     }
 }
Example #16
0
void IRMutator::visit(const For *op) {
    Expr min = mutate(op->min);
    Expr extent = mutate(op->extent);
    Stmt body = mutate(op->body);
    if (min.same_as(op->min) &&
        extent.same_as(op->extent) &&
        body.same_as(op->body)) {
        stmt = op;
    } else {
        stmt = For::make(op->name, min, extent, op->for_type, body);
    }
}
Example #17
0
void print_merged_ir( vector<Stmt *> ir )
{
    unsigned int i;

    for ( i = 0; i < ir.size(); i++ )
    {
        Stmt *stmt = ir.at(i);
        assert(stmt);

        cout << stmt->ir_address << "\t\t" << stmt->tostring() << endl;
    }
}
Example #18
0
Stmt Pipeline::make(std::string name, Stmt produce, Stmt update, Stmt consume) {
    internal_assert(produce.defined()) << "Pipeline of undefined\n";
    // update is allowed to be null
    internal_assert(consume.defined()) << "Pipeline of undefined\n";

    Pipeline *node = new Pipeline;
    node->name = name;
    node->produce = produce;
    node->update = update;
    node->consume = consume;
    return node;
}
Example #19
0
void BlockStmt::genCode(const Label& next) {
  const unsigned n = stmts->size();
  for (unsigned i = 0; i < n; i++) {
    Stmt *stmt = (*stmts)[i];
    if (i < n-1) {
      Label nxt;
      stmt->genCode(nxt);
      cout << nxt << ":" << endl;
    } else
      stmt->genCode(next);
  }
}
Example #20
0
 void visit(const LetStmt *op) {
     Expr value = mutate(op->value);
     if (value.type() == Int(32)) alignment_info.push(op->name, 
                                                      modulus_remainder(value, alignment_info));
     Stmt body = mutate(op->body);
     if (value.type() == Int(32)) alignment_info.pop(op->name);        
     if (value.same_as(op->value) && body.same_as(op->body)) {
         stmt = op;
     } else {
         stmt = LetStmt::make(op->name, value, body);
     }
 }
Example #21
0
bool Interpret::EvaluateExpression(const string& expr_str) {
	string trim = expr_str;
	trim.erase(trim.find_last_not_of(" \n\r\t")+1);

	if (trim == "") {
		return true;
	}

	ScopeTracer tracer(session(), "Interpret::EvaluateExpression()");
	assert(_repl_module != NULL);
	assert(_repl_block != NULL);

	session()->diagnostic()->resetReport();

	// Parses the expression.
	Parser parser(trim, session());
	Stmt* stmt = parser.parseStatement();
	if (session()->diagnostic()->mostSignificantLevel() <= REPORT_ERROR) {
		return false;
	}

	// resolving
	Resolver resolver(session());
	resolver.resolveAst(stmt);

	_repl_block->addStatement(stmt);
	stmt->parent(_repl_block);

	// Resolves names.
	resolver.resolveSymbol(stmt);

	if (session()->diagnostic()->mostSignificantLevel() <= REPORT_ERROR) {
		return false;
	}

	if (session()->config()->print_ast()) {
		AstPrinter astPrinter(session(), stdout, session()->str_table());
		astPrinter.print(stmt);
	}

	// Evaluates it.
	Evaluator eval(this);
	_eval = &eval;
	Value* v = eval.evaluate(stmt);

	if (v) {
		printf("%s\n", v->toString().c_str());
	}

	env_curr()->clear();

	return true;
}
Example #22
0
void SimpleInliner::copyFunctionBody(void)
{
  Stmt *Body = CurrentFD->getBody();
  TransAssert(Body && "NULL Body!");

  std::string FuncBodyStr("");
  RewriteHelper->getStmtString(Body, FuncBodyStr);
  TransAssert(FuncBodyStr[0] == '{');

  SourceLocation StartLoc = Body->getLocStart();
  const char *StartBuf = SrcManager->getCharacterData(StartLoc);

  std::vector< std::pair<ReturnStmt *, int> > SortedReturnStmts;
  sortReturnStmtsByOffs(StartBuf, SortedReturnStmts);

  // Now we start rewriting
  int Delta = 1; // skip the first { symbol
  FuncBodyStr.insert(Delta, "\n");
  ++Delta;
  for(SmallVector<std::string, 10>::iterator I = ParmStrings.begin(),
       E = ParmStrings.end(); I != E; ++I) {
    std::string PStr = (*I);
    FuncBodyStr.insert(Delta, PStr);
    Delta += PStr.size();
  }

  // restore the effect of {
  Delta--;
  int ReturnSZ = 6;
  std::string TmpVarStr = TmpVarName + " = ";
  int TmpVarNameSize = static_cast<int>(TmpVarStr.size());

  for(std::vector< std::pair<ReturnStmt *, int> >::iterator
      I = SortedReturnStmts.begin(), E = SortedReturnStmts.end(); 
      I != E; ++I) {

    ReturnStmt *RS = (*I).first;
    int Off = (*I).second + Delta;
    Expr *Exp = RS->getRetValue();
    if (Exp) {
      const Type *T = Exp->getType().getTypePtr();
      if (!T->isVoidType()) {
        FuncBodyStr.replace(Off, ReturnSZ, TmpVarStr);
        Delta += (TmpVarNameSize - ReturnSZ);
        continue;
      }
    }
    FuncBodyStr.replace(Off, ReturnSZ, "");
    Delta -= ReturnSZ;
  }

  RewriteHelper->addStringBeforeStmt(TheStmt, FuncBodyStr, NeedParen);
}
Example #23
0
void Func::realize(Buffer dst) {
    if (!compiled_module.wrapped_function) {
   
        assert(func.defined() && "Can't realize NULL function handle");
        assert(value().defined() && "Can't realize undefined function");
        
        Stmt stmt = lower();
        
        // Infer arguments
        InferArguments infer_args;
        stmt.accept(&infer_args);
        
        Argument me(name(), true, Int(1));
        infer_args.arg_types.push_back(me);
        arg_values = infer_args.arg_values;
        arg_values.push_back(dst.raw_buffer());
        image_param_args = infer_args.image_param_args;

        Internal::log(2) << "Inferred argument list:\n";
        for (size_t i = 0; i < infer_args.arg_types.size(); i++) {
            Internal::log(2) << infer_args.arg_types[i].name << ", " 
                             << infer_args.arg_types[i].type << ", " 
                             << infer_args.arg_types[i].is_buffer << "\n";
        }
        
        StmtCompiler cg;
        cg.compile(stmt, name(), infer_args.arg_types);

        if (log::debug_level >= 3) {
            cg.compile_to_native(name() + ".s", true);
            cg.compile_to_bitcode(name() + ".bc");
            std::ofstream stmt_debug((name() + ".stmt").c_str());
            stmt_debug << stmt;
        }

        compiled_module = cg.compile_to_function_pointers();

        if (error_handler) compiled_module.set_error_handler(error_handler);
        else compiled_module.set_error_handler(NULL);
    } else {
        // Update the address of the buffer we're realizing into
        arg_values[arg_values.size()-1] = dst.raw_buffer();
        // update the addresses of the image param args
        for (size_t i = 0; i < image_param_args.size(); i++) {
            Buffer b = image_param_args[i].second.get_buffer();
            assert(b.defined() && "An ImageParam is not bound to a buffer");
            arg_values[image_param_args[i].first] = b.raw_buffer();
        }
    }

    compiled_module.wrapped_function(&(arg_values[0]));
    
}
Example #24
0
 bool VisitStmt(Stmt *s) {
     // Only care about If statements.
     if (isa<IfStmt>(s)) {
         IfStmt *IfStatement = cast<IfStmt>(s);
         Stmt *Then = IfStatement->getThen();
         TheRewriter.InsertText(Then->getLocStart(), "// the 'if' part\n", true, true);
         Stmt *Else = IfStatement->getElse();
         if (Else)
             TheRewriter.InsertText(Else->getLocStart(), "// the 'else' part\n", true, true);
     }
     return true;
 }
Example #25
0
Stmt IRMutator2::visit(const For *op) {
    Expr min = mutate(op->min);
    Expr extent = mutate(op->extent);
    Stmt body = mutate(op->body);
    if (min.same_as(op->min) &&
        extent.same_as(op->extent) &&
        body.same_as(op->body)) {
        return op;
    }
    return For::make(op->name, std::move(min), std::move(extent),
                         op->for_type, op->device_api, std::move(body));
}
Example #26
0
    void visit(const Realize *op) {
        Stmt body = mutate(op->body);

        IsBufferSpecial special(op->name);
        op->accept(&special);

        // Get the function associated with this realization, which
        // contains the explicit fold directives from the schedule.
        auto func_it = env.find(op->name);
        Function func = func_it != env.end() ? func_it->second : Function();

        if (special.special) {
            for (const StorageDim &i : func.schedule().storage_dims()) {
                user_assert(!i.fold_factor.defined())
                    << "Dimension " << i.var << " of " << op->name
                    << " cannot be folded because it is accessed by extern or device stages.\n";
            }

            debug(3) << "Not attempting to fold " << op->name << " because its buffer is used\n";
            if (body.same_as(op->body)) {
                stmt = op;
            } else {
                stmt = Realize::make(op->name, op->types, op->bounds, op->condition, body);
            }
        } else {
            // Don't attempt automatic storage folding if there is
            // more than one produce node for this func.
            bool explicit_only = count_producers(body, op->name) != 1;
            AttemptStorageFoldingOfFunction folder(func, explicit_only);
            debug(3) << "Attempting to fold " << op->name << "\n";
            body = folder.mutate(body);

            if (body.same_as(op->body)) {
                stmt = op;
            } else if (folder.dims_folded.empty()) {
                stmt = Realize::make(op->name, op->types, op->bounds, op->condition, body);
            } else {
                Region bounds = op->bounds;

                for (size_t i = 0; i < folder.dims_folded.size(); i++) {
                    int d = folder.dims_folded[i].dim;
                    Expr f = folder.dims_folded[i].factor;
                    internal_assert(d >= 0 &&
                                    d < (int)bounds.size());

                    bounds[d] = Range(0, f);
                }

                stmt = Realize::make(op->name, op->types, bounds, op->condition, body);
            }
        }
    }
Example #27
0
void IRRewriter::visit(const Func *f) {
  Stmt body = rewrite(f->getBody());

  if (body == f->getBody()) {
    func = *f;
  }
  else {
    if (!body.defined()) {
      body = Pass::make();
    }
    func = Func(*f, body);
  }
}
Example #28
0
    void visit(const Allocate *op) {
        allocs.push(op->name, 1);
        Stmt body = mutate(op->body);

        if (allocs.contains(op->name)) {
            stmt = body;
            allocs.pop(op->name);
        } else if (body.same_as(op->body)) {
            stmt = op;
        } else {
            stmt = Allocate::make(op->name, op->type, op->extents, op->condition, body, op->new_expr, op->free_function);
        }
    }
Example #29
0
string print_loop_nest(const vector<Function> &output_funcs) {
    // Do the first part of lowering:

    // Compute an environment
    map<string, Function> env;
    for (Function f : output_funcs) {
        populate_environment(f, env);
    }

    // Create a deep-copy of the entire graph of Funcs.
    vector<Function> outputs;
    std::tie(outputs, env) = deep_copy(output_funcs, env);

    // Output functions should all be computed and stored at root.
    for (Function f: outputs) {
        Func(f).compute_root().store_root();
    }

    // Ensure that all ScheduleParams become well-defined constant Exprs.
    for (auto &f : env) {
        f.second.substitute_schedule_param_exprs();
    }

    // Substitute in wrapper Funcs
    env = wrap_func_calls(env);

    // Compute a realization order
    vector<string> order = realization_order(outputs, env);

    // Try to simplify the RHS/LHS of a function definition by propagating its
    // specializations' conditions
    simplify_specializations(env);

    // For the purposes of printing the loop nest, we don't want to
    // worry about which features are and aren't enabled.
    Target target = get_host_target();
    for (DeviceAPI api : all_device_apis) {
        target.set_feature(target_feature_for_device_api(DeviceAPI(api)));
    }

    bool any_memoized = false;
    // Schedule the functions.
    Stmt s = schedule_functions(outputs, order, env, target, any_memoized);

    // Now convert that to pseudocode
    std::ostringstream sstr;
    PrintLoopNest pln(sstr, env);
    s.accept(&pln);
    return sstr.str();
}
Example #30
0
    void visit(const Allocate *op) {
        int idx = get_func_id(op->name);

        vector<Expr> new_extents;
        bool all_extents_unmodified = true;
        for (size_t i = 0; i < op->extents.size(); i++) {
            new_extents.push_back(mutate(op->extents[i]));
            all_extents_unmodified &= new_extents[i].same_as(op->extents[i]);
        }
        Expr condition = mutate(op->condition);

        bool on_stack;
        Expr size = compute_allocation_size(new_extents, condition, op->type, op->name, on_stack);
        func_alloc_sizes.push(op->name, {on_stack, size});

        // compute_allocation_size() might return a zero size, if the allocation is
        // always conditionally false. remove_dead_allocations() is called after
        // inject_profiling() so this is a possible scenario.
        if (!is_zero(size) && on_stack) {
            const int64_t *int_size = as_const_int(size);
            internal_assert(int_size != NULL); // Stack size is always a const int
            func_stack_current[idx] += *int_size;
            func_stack_peak[idx] = std::max(func_stack_peak[idx], func_stack_current[idx]);
            debug(3) << "  Allocation on stack: " << op->name << "(" << size << ") in pipeline " << pipeline_name
                     << "; current: " << func_stack_current[idx] << "; peak: " << func_stack_peak[idx] << "\n";
        }

        Stmt body = mutate(op->body);
        Expr new_expr;
        if (op->new_expr.defined()) {
            new_expr = mutate(op->new_expr);
        }
        if (all_extents_unmodified &&
            body.same_as(op->body) &&
            condition.same_as(op->condition) &&
            new_expr.same_as(op->new_expr)) {
            stmt = op;
        } else {
            stmt = Allocate::make(op->name, op->type, new_extents, condition, body, new_expr, op->free_function);
        }

        if (!is_zero(size) && !on_stack) {
            Expr profiler_pipeline_state = Variable::make(Handle(), "profiler_pipeline_state");
            debug(3) << "  Allocation on heap: " << op->name << "(" << size << ") in pipeline " << pipeline_name << "\n";
            Expr set_task = Call::make(Int(32), "halide_profiler_memory_allocate",
                                       {profiler_pipeline_state, idx, size}, Call::Extern);
            stmt = Block::make(Evaluate::make(set_task), stmt);
        }
    }