Mark all stack values available in an inlined callee

For DecRef -> DecRefNZ transitions.  Any value on the stack
at the callsite must outlive the callee.
Esse commit está contido em:
Jordan DeLong
2013-05-17 20:06:00 -07:00
commit de Sara Golemon
commit c14f38d855
4 arquivos alterados com 38 adições e 9 exclusões
+16 -5
Ver Arquivo
@@ -38,11 +38,10 @@ StackValueInfo getStackValue(SSATmp* sp, uint32_t index) {
case DefSP:
return {};
case ReDefGeneratorSP: {
auto srcInst = inst->getSrc(0)->inst();
assert(srcInst->op() == StashGeneratorSP);
return getStackValue(srcInst->getSrc(0), index);
}
case ReDefGeneratorSP:
case StashGeneratorSP:
return getStackValue(inst->getSrc(0), index);
case ReDefSP:
return getStackValue(inst->getSrc(1), index);
@@ -153,6 +152,18 @@ StackValueInfo getStackValue(SSATmp* sp, uint32_t index) {
not_reached();
}
smart::vector<SSATmp*> collectStackValues(SSATmp* sp, uint32_t stackDepth) {
smart::vector<SSATmp*> ret;
ret.reserve(stackDepth);
for (uint32_t i = 0; i < stackDepth; ++i) {
auto const value = getStackValue(sp, i).value;
if (value) {
ret.push_back(value);
}
}
return ret;
}
//////////////////////////////////////////////////////////////////////
static void copyPropSrc(IRInstruction* inst, int index) {
@@ -167,6 +167,15 @@ struct StackValueInfo {
*/
StackValueInfo getStackValue(SSATmp* stack, uint32_t index);
/*
* Return this list of all values that are known to be on the stack
* given the particular depth.
*
* This function is used for computing available value for
* DecRef->DecRefNZ conversions in tracebuilder.
*/
smart::vector<SSATmp*> collectStackValues(SSATmp* sp, uint32_t stackDepth);
/*
* Propagate very simple copies on the given instruction.
* Specifically, Movs, and also IncRefs of non-refcounted types.
+12 -3
Ver Arquivo
@@ -73,7 +73,7 @@ bool TraceBuilder::isValueAvailable(SSATmp* tmp) const {
while (true) {
if (m_refCountedMemValue == tmp) return true;
if (anyLocalHasValue(tmp)) return true;
if (callerLocalHasValue(tmp)) return true;
if (callerHasValueAvailable(tmp)) return true;
IRInstruction* srcInstr = tmp->inst();
Opcode srcOpcode = srcInstr->op();
@@ -126,6 +126,12 @@ void TraceBuilder::trackDefInlineFP(IRInstruction* inst) {
m_spOffset = savedSPOff;
m_spValue = savedSP;
auto const stackValues = collectStackValues(m_spValue, m_spOffset);
for (DEBUG_ONLY auto& val : stackValues) {
FTRACE(4, " marking caller stack value available: {}\n",
val->toString());
}
m_inlineSavedStates.push_back(createState());
/*
@@ -146,6 +152,9 @@ void TraceBuilder::trackDefInlineFP(IRInstruction* inst) {
m_callerAvailableValues.insert(m_callerAvailableValues.end(),
m_localValues.begin(),
m_localValues.end());
m_callerAvailableValues.insert(m_callerAvailableValues.end(),
stackValues.begin(),
stackValues.end());
m_localValues.clear();
m_localTypes.clear();
@@ -603,7 +612,7 @@ SSATmp* TraceBuilder::preOptimizeDecRefThis(IRInstruction* inst) {
* frame, so debug_backtrace() can't see a non-live pointer value.
*/
if (thisInst->op() == IncRef &&
callerLocalHasValue(thisInst->getSrc(0))) {
callerHasValueAvailable(thisInst->getSrc(0))) {
gen(DecRefNZ, thiss);
inst->convertToNop();
return nullptr;
@@ -919,7 +928,7 @@ bool TraceBuilder::anyLocalHasValue(SSATmp* tmp) const {
tmp) != m_localValues.end();
}
bool TraceBuilder::callerLocalHasValue(SSATmp* tmp) const {
bool TraceBuilder::callerHasValueAvailable(SSATmp* tmp) const {
return std::find(m_callerAvailableValues.begin(),
m_callerAvailableValues.end(),
tmp) != m_callerAvailableValues.end();
+1 -1
Ver Arquivo
@@ -316,7 +316,7 @@ private:
SSATmp* getLocalValue(unsigned id) const;
bool isValueAvailable(SSATmp*) const;
bool anyLocalHasValue(SSATmp*) const;
bool callerLocalHasValue(SSATmp*) const;
bool callerHasValueAvailable(SSATmp*) const;
void updateLocalRefValues(SSATmp* oldRef, SSATmp* newRef);
void trackDefInlineFP(IRInstruction* inst);
void trackInlineReturn(IRInstruction* inst);