void Inst::dumpExtras(const Cfg *Func) const { Ostream &Str = Func->getContext()->getStrDump(); bool First = true; // Print "LIVEEND={a,b,c}" for all source operands whose live ranges // are known to end at this instruction. if (Func->getContext()->isVerbose(IceV_Liveness)) { for (SizeT I = 0; I < getSrcSize(); ++I) { Operand *Src = getSrc(I); SizeT NumVars = Src->getNumVars(); for (SizeT J = 0; J < NumVars; ++J) { const Variable *Var = Src->getVar(J); if (isLastUse(Var)) { if (First) Str << " // LIVEEND={"; else Str << ","; Var->dump(Func); First = false; } } } if (!First) Str << "}"; } }
void Inst::liveness(InstNumberT InstNumber, llvm::BitVector &Live, Liveness *Liveness, const CfgNode *Node) { assert(!isDeleted()); if (llvm::isa<InstFakeKill>(this)) return; std::vector<InstNumberT> &LiveBegin = Liveness->getLiveBegin(Node); std::vector<InstNumberT> &LiveEnd = Liveness->getLiveEnd(Node); Dead = false; if (Dest) { SizeT VarNum = Liveness->getLiveIndex(Dest); if (Live[VarNum]) { Live[VarNum] = false; LiveBegin[VarNum] = InstNumber; } else { if (!hasSideEffects()) Dead = true; } } if (Dead) return; // Phi arguments only get added to Live in the predecessor node, but // we still need to update LiveRangesEnded. bool IsPhi = llvm::isa<InstPhi>(this); resetLastUses(); SizeT VarIndex = 0; for (SizeT I = 0; I < getSrcSize(); ++I) { Operand *Src = getSrc(I); SizeT NumVars = Src->getNumVars(); for (SizeT J = 0; J < NumVars; ++J, ++VarIndex) { const Variable *Var = Src->getVar(J); SizeT VarNum = Liveness->getLiveIndex(Var); if (!Live[VarNum]) { setLastUse(VarIndex); if (!IsPhi) { Live[VarNum] = true; // For a variable in SSA form, its live range can end at // most once in a basic block. However, after lowering to // two-address instructions, we end up with sequences like // "t=b;t+=c;a=t" where t's live range begins and ends // twice. ICE only allows a variable to have a single // liveness interval in a basic block (except for blocks // where a variable is live-in and live-out but there is a // gap in the middle, and except for the special // InstFakeKill instruction that can appear multiple // times in the same block). Therefore, this lowered // sequence needs to represent a single conservative live // range for t. Since the instructions are being traversed // backwards, we make sure LiveEnd is only set once by // setting it only when LiveEnd[VarNum]==0 (sentinel value). // Note that it's OK to set LiveBegin multiple times because // of the backwards traversal. if (LiveEnd[VarNum] == 0) { LiveEnd[VarNum] = InstNumber; } } } } } }
void Inst::emitSources(const Cfg *Func) const { Ostream &Str = Func->getContext()->getStrEmit(); for (SizeT I = 0; I < getSrcSize(); ++I) { if (I > 0) Str << ", "; getSrc(I)->emit(Func); } }
// Find the source operand corresponding to the incoming edge for the // given node. TODO: This uses a linear-time search, which could be // improved if it becomes a problem. Operand *InstPhi::getOperandForTarget(CfgNode *Target) const { for (SizeT I = 0; I < getSrcSize(); ++I) { if (Labels[I] == Target) return getSrc(I); } llvm_unreachable("Phi target not found"); return NULL; }
void GPUBlurFilter::setStdDev(float stdDev) { m_StdDev = stdDev; m_pGaussCurveTex = calcBlurKernelTex(m_StdDev, 1, m_bUseFloatKernel); setDimensions(getSrcSize(), stdDev); IntRect destRect2(IntPoint(0,0), getDestRect().size()); m_pProjection2 = ImagingProjectionPtr(new ImagingProjection( getDestRect().size(), destRect2)); }
void InstPhi::dump(const Cfg *Func) const { Ostream &Str = Func->getContext()->getStrDump(); dumpDest(Func); Str << " = phi " << getDest()->getType() << " "; for (SizeT I = 0; I < getSrcSize(); ++I) { if (I > 0) Str << ", "; Str << "[ "; getSrc(I)->dump(Func); Str << ", %" << Labels[I]->getName() << " ]"; } }
// Updates liveness for a particular operand based on the given // predecessor edge. Doesn't mark the operand as live if the Phi // instruction is dead or deleted. void InstPhi::livenessPhiOperand(llvm::BitVector &Live, CfgNode *Target, Liveness *Liveness) { if (isDeleted() || Dead) return; for (SizeT I = 0; I < getSrcSize(); ++I) { if (Labels[I] == Target) { if (Variable *Var = llvm::dyn_cast<Variable>(getSrc(I))) { SizeT SrcIndex = Liveness->getLiveIndex(Var); if (!Live[SrcIndex]) { setLastUse(I); Live[SrcIndex] = true; } } return; } } llvm_unreachable("Phi operand not found for specified target node"); }
// TODO: A Switch instruction (and maybe others) can add duplicate // edges. We may want to de-dup Phis and validate consistency (i.e., // the source operands are the same for duplicate edges), though it // seems the current lowering code is OK with this situation. void InstPhi::addArgument(Operand *Source, CfgNode *Label) { Labels[getSrcSize()] = Label; addSource(Source); }