* Summarize HIR cost estimates on Compiler.
These cost estimates are made on HIR and are not used by the backend.
Stash them before converting the function to LIR and report them at the
end of compilation.
* Stop maintaining costs in the backend.
The backend does not use the tree cost estimates.
* Remove a bit more cost maintenance.
* Address PR feedback.
#ifdef DEBUG
genInterruptibleUsed = true;
- unsigned totalCostEx = 0;
- unsigned totalCostSz = 0;
// You have to be careful if you create basic blocks from now on
compiler->fgSafeBasicBlockCreation = false;
}
}
}
-
- // TODO-LIR: the cost accounting performed below is incorrect: each operator's cost includes the
- // cost of its operands, so the total cost of the block is grossly overestimated. Fixing
- // this requires the ability to calculate the cost of the operator itself.
- //
- // totalCostEx += (UINT64)node->gtCostEx * block->getBBWeight(compiler);
- // totalCostSz += (UINT64)node->gtCostSz;
-
#endif // DEBUG
genCodeForTreeNode(node);
if (compiler->verbose)
{
printf("\n# ");
- printf("totalCostEx = %6d, totalCostSz = %5d ", totalCostEx, totalCostSz);
+ printf("compCycleEstimate = %6d, compSizeEstimate = %5d ", compiler->compCycleEstimate, compiler->compSizeEstimate);
printf("%s\n", compiler->info.compFullName);
}
#endif
#ifdef DEBUG
genInterruptibleUsed = true;
- UINT64 totalCostEx = 0;
- UINT64 totalCostSz = 0;
// You have to be careful if you create basic blocks from now on
compiler->fgSafeBasicBlockCreation = false;
}
}
}
-
- // TODO-LIR: the cost accounting performed below is incorrect: each operator's cost includes the
- // cost of its operands, so the total cost of the block is grossly overestimated. Fixing
- // this requires the ability to calculate the cost of the operator itself.
- //
- // totalCostEx += (UINT64)node->gtCostEx * block->getBBWeight(compiler);
- // totalCostSz += (UINT64)node->gtCostSz;
-
#endif // DEBUG
genCodeForTreeNode(node);
if (compiler->verbose)
{
printf("\n# ");
- printf("totalCostEx = %6d, totalCostSz = %5d ", totalCostEx, totalCostSz);
+ printf("compCycleEstimate = %6d, compSizeEstimate = %5d ", compiler->compCycleEstimate, compiler->compSizeEstimate);
printf("%s\n", compiler->info.compFullName);
}
#endif
#ifdef DEBUG
genInterruptibleUsed = true;
- unsigned stmtNum = 0;
- UINT64 totalCostEx = 0;
- UINT64 totalCostSz = 0;
// You have to be careful if you create basic blocks from now on
compiler->fgSafeBasicBlockCreation = false;
}
}
}
-
- // TODO-LIR: the cost accounting performed below is incorrect: each operator's cost includes the
- // cost of its operands, so the total cost of the block is grossly overestimated. Fixing
- // this requires the ability to calculate the cost of the operator itself.
- //
- // totalCostEx += (UINT64)node->gtCostEx * block->getBBWeight(compiler);
- // totalCostSz += (UINT64)node->gtCostSz;
-
#endif // DEBUG
genCodeForTreeNode(node);
if (compiler->verbose)
{
printf("\n# ");
- printf("totalCostEx = %6d, totalCostSz = %5d ", totalCostEx, totalCostSz);
+ printf("compCycleEstimate = %6d, compSizeEstimate = %5d ", compiler->compCycleEstimate, compiler->compSizeEstimate);
printf("%s\n", compiler->info.compFullName);
}
#endif
#ifdef DEBUG
fgDebugCheckLinks(compStressCompile(STRESS_REMORPH_TREES, 50));
+
+ // Stash the current estimate of the function's size if necessary.
+ if (verbose)
+ {
+ compSizeEstimate = 0;
+ compCycleEstimate = 0;
+ for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext)
+ {
+ for (GenTreeStmt* statement = block->firstStmt(); statement != nullptr; statement = statement->getNextStmt())
+ {
+ compSizeEstimate += statement->GetCostSz();
+ compCycleEstimate += statement->GetCostEx();
+ }
+ }
+ }
#endif
#ifndef LEGACY_BACKEND
bool compCodeGenDone;
int64_t compNumStatementLinksTraversed; // # of links traversed while doing debug checks
bool fgNormalizeEHDone; // Has the flowgraph EH normalization phase been done?
+ size_t compSizeEstimate; // The estimated size of the method as per `gtSetEvalOrder`.
+ size_t compCycleEstimate; // The estimated cycle count of the method as per `gtSetEvalOrder`
#endif // DEBUG
bool fgLocalVarLivenessDone; // Note that this one is used outside of debug.
loResult->gtType = TYP_INT;
GenTree* hiResult = m_compiler->gtNewLclLNode(varNum, TYP_INT);
- hiResult->CopyCosts(loResult);
BlockRange().InsertAfter(loResult, hiResult);
if (varDsc->lvPromoted)
loResult->gtType = TYP_INT;
GenTree* hiResult = m_compiler->gtNewLclFldNode(loResult->gtLclNum, TYP_INT, loResult->gtLclOffs + 4);
- hiResult->CopyCosts(loResult);
BlockRange().InsertAfter(loResult, hiResult);
return FinalizeDecomposition(use, loResult, hiResult);
m_compiler->lvaIncRefCnts(tree);
m_compiler->lvaIncRefCnts(hiStore);
- hiStore->CopyCosts(tree);
BlockRange().InsertAfter(tree, hiStore);
return hiStore->gtNext;
BlockRange().Remove(tree);
hiResult = new (m_compiler, GT_CNS_INT) GenTreeIntCon(TYP_INT, 0);
- hiResult->CopyCosts(loResult);
BlockRange().InsertAfter(loResult, hiResult);
}
else
loResult->gtType = TYP_INT;
GenTree* hiResult = new (m_compiler, GT_CNS_INT) GenTreeIntCon(TYP_INT, hiVal);
- hiResult->CopyCosts(loResult);
BlockRange().InsertAfter(loResult, hiResult);
return FinalizeDecomposition(use, loResult, hiResult);
storeIndHigh->gtFlags = (storeIndLow->gtFlags & (GTF_ALL_EFFECT | GTF_LIVENESS_MASK));
storeIndHigh->gtFlags |= GTF_REVERSE_OPS;
- m_compiler->gtPrepareCost(storeIndHigh);
-
BlockRange().InsertAfter(storeIndLow, dataHigh, addrBaseHigh, addrHigh, storeIndHigh);
return storeIndHigh;
new (m_compiler, GT_LEA) GenTreeAddrMode(TYP_REF, addrBaseHigh, nullptr, 0, genTypeSize(TYP_INT));
GenTreePtr indHigh = new (m_compiler, GT_IND) GenTreeIndir(GT_IND, TYP_INT, addrHigh, nullptr);
- m_compiler->gtPrepareCost(indHigh);
-
BlockRange().InsertAfter(indLow, addrBaseHigh, addrHigh, indHigh);
return FinalizeDecomposition(use, indLow, indHigh);
loResult->gtOp.gtOp1 = loOp1;
GenTree* hiResult = new (m_compiler, GT_NOT) GenTreeOp(GT_NOT, TYP_INT, hiOp1, nullptr);
- hiResult->CopyCosts(loResult);
BlockRange().InsertAfter(loResult, hiResult);
return FinalizeDecomposition(use, loResult, hiResult);
GenTree* hiResult = m_compiler->gtNewOperNode(GT_NEG, TYP_INT, hiAdjust);
hiResult->gtFlags = tree->gtFlags;
- // Annotate new nodes with costs. This will re-cost the hiOp1 tree as well.
- m_compiler->gtPrepareCost(hiResult);
-
BlockRange().InsertAfter(loResult, zero, hiAdjust, hiResult);
return FinalizeDecomposition(use, loResult, hiResult);
loResult->gtOp.gtOp2 = loOp2;
GenTree* hiResult = new (m_compiler, oper) GenTreeOp(GetHiOper(oper), TYP_INT, hiOp1, hiOp2);
- hiResult->CopyCosts(loResult);
BlockRange().InsertAfter(loResult, hiResult);
if ((oper == GT_ADD) || (oper == GT_SUB))
compiler->lvaTable[lclNum].incRefCnts(blockWeight, compiler);
GenTreeLclVar* store = compiler->gtNewTempAssign(lclNum, node)->AsLclVar();
- store->CopyCosts(node);
GenTree* load =
new (compiler, GT_LCL_VAR) GenTreeLclVar(store->TypeGet(), store->AsLclVarCommon()->GetLclNum(), BAD_IL_OFFSET);
- compiler->gtPrepareCost(load);
m_range->InsertAfter(node, store, load);
info->structDesc.eightByteSizes[ctr]),
argListPtr->gtOp.gtOp1);
- // CopyCosts
- newOper->CopyCosts(argListPtr->gtOp.gtOp1);
-
// Splice in the new GT_PUTARG_REG node in the GT_LIST
ReplaceArgWithPutArgOrCopy(&argListPtr->gtOp.gtOp1, newOper);
}
// Create a new GT_PUTARG_REG node with op1
GenTreePtr newOper = comp->gtNewOperNode(GT_PUTARG_REG, curTyp, curOp);
- // CopyCosts
- newOper->CopyCosts(argListPtr->gtOp.gtOp1);
-
// Splice in the new GT_PUTARG_REG node in the GT_LIST
ReplaceArgWithPutArgOrCopy(&argListPtr->gtOp.gtOp1, newOper);
}
#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
}
- putArg->CopyCosts(arg);
-
if (arg->InReg())
{
putArg->SetInReg();
var_types intType = (type == TYP_DOUBLE) ? TYP_LONG : TYP_INT;
GenTreePtr intArg = comp->gtNewOperNode(GT_COPY, intType, arg);
- intArg->CopyCosts(arg);
info->node = intArg;
ReplaceArgWithPutArgOrCopy(ppArg, intArg);
GenTreeAddrMode(TYP_REF, originalThisExpr, nullptr, 0, comp->eeGetEEInfo()->offsetOfDelegateInstance);
GenTree* newThis = comp->gtNewOperNode(GT_IND, TYP_REF, newThisAddr);
- newThis->SetCosts(IND_COST_EX, 2);
BlockRange().InsertAfter(originalThisExpr, newThisAddr, newThis);
GenTreeAddrMode* addrMode = new (comp, GT_LEA) GenTreeAddrMode(addrModeType, base, index, scale, offset);
- addrMode->CopyCosts(addr);
addrMode->gtRsvdRegs = addr->gtRsvdRegs;
addrMode->gtFlags |= (addr->gtFlags & (GTF_ALL_EFFECT | GTF_IND_FLAGS));
GenTreePtr leaNode = new (comp, GT_LEA) GenTreeAddrMode(arrElem->TypeGet(), leaBase, leaIndexNode, scale, offset);
leaNode->gtFlags |= GTF_REVERSE_OPS;
- // Set the costs for all of the new nodes. Depends on the new nodes all participating in the
- // dataflow tree rooted at `leaNode`.
- comp->gtPrepareCost(leaNode);
-
BlockRange().InsertBefore(insertionPoint, leaNode);
LIR::Use arrElemUse;
GenTreeCopyOrReload* newNode = new (compiler, oper) GenTreeCopyOrReload(oper, treeType, tree);
assert(refPosition->registerAssignment != RBM_NONE);
- newNode->CopyCosts(tree);
newNode->SetRegNumByIdx(refPosition->assignedReg(), multiRegIdx);
newNode->gtLsraInfo.isLsraAdded = true;
newNode->gtLsraInfo.isLocalDefUse = false;
// Since destination is known to be a SIMD type, src must be a SIMD type too
// though we cannot figure it out easily enough. Transform src into
// GT_IND(src) of simdType.
- //
- // We need to initialize costs on indir so that CopyCosts() while creating
- // an addrmode will not hit asserts. These costs are not used further down
- // but setting them to a reasonable value based on the logic in gtSetEvalOrder().
GenTree* indir = comp->gtNewOperNode(GT_IND, simdType, srcAddr);
- indir->SetCosts(IND_COST_EX, 2);
BlockRange().InsertAfter(srcAddr, indir);
cpBlk->gtGetOp1()->gtOp.gtOp2 = indir;
// Create the call node
GenTreeCall* call = comp->gtNewCallNode(CT_USER_FUNC, callHnd, tree->gtType, args);
call = comp->fgMorphArgs(call);
- call->CopyCosts(tree);
#ifdef FEATURE_READYTORUN_COMPILER
call->gtCall.setEntryPoint(entryPoint);
#endif
store->gtFlags |= GTF_REVERSE_OPS;
}
- store->CopyCosts(assignment);
-
// TODO: JIT dump
// Remove the GT_IND node and replace the assignment node with the store
if (!isLHSOfAssignment)
{
GenTree* ind = comp->gtNewOperNode(GT_IND, node->TypeGet(), node);
- ind->CopyCosts(node);
node->SetOper(GT_CLS_VAR_ADDR);
node->gtType = TYP_BYREF;
GenTree* address = new (comp, GT_LEA) GenTreeAddrMode(TYP_BYREF, simdNode->gtOp1, simdNode->gtOp2,
baseTypeSize, offsetof(CORINFO_Array, u1Elems));
GenTree* ind = comp->gtNewOperNode(GT_IND, simdType, address);
- address->CopyCosts(simdNode);
- ind->CopyCosts(simdNode);
BlockRange().InsertBefore(simdNode, address, ind);
use.ReplaceWith(comp, ind);