void InstFcmp::dump(const Cfg *Func) const { Ostream &Str = Func->getContext()->getStrDump(); dumpDest(Func); Str << " = fcmp " << InstFcmpAttributes[getCondition()].DisplayString << " " << getSrc(0)->getType() << " "; dumpSources(Func); }
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 << "}"; } }
SSATmp* TraceBuilder::preOptimizeDecRefThis(IRInstruction* inst) { /* * If $this is available, convert to an instruction sequence that * doesn't need to test if it's already live. */ if (isThisAvailable()) { auto const thiss = gen(LdThis, m_fpValue); auto const thisInst = thiss->inst(); /* * DecRef optimization for $this in an inlined frame: if a caller * local contains the $this, we know it can't go to zero and can * switch DecRef to DecRefNZ. * * It's ok not to do DecRefThis (which normally nulls out the ActRec * $this), because there is still a reference to it in the caller * frame, so debug_backtrace() can't see a non-live pointer value. */ if (thisInst->op() == IncRef && callerLocalHasValue(thisInst->getSrc(0))) { gen(DecRefNZ, thiss); inst->convertToNop(); return nullptr; } assert(inst->getSrc(0) == m_fpValue); gen(DecRef, thiss); inst->convertToNop(); return nullptr; } return nullptr; }
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; } } } } } }
// 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 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); } }
void InstCast::dump(const Cfg *Func) const { Ostream &Str = Func->getContext()->getStrDump(); dumpDest(Func); Str << " = " << InstCastAttributes[getCastKind()].DisplayString << " " << getSrc(0)->getType() << " "; dumpSources(Func); Str << " to " << getDest()->getType(); }
unsigned int Instruction::srcCount(unsigned int mask, bool singleFile) const { unsigned int i, n; if (singleFile) { unsigned int s = ffs(mask); if (!s) return 0; for (i = s--; srcExists(i); ++i) if (getSrc(i)->reg.file != getSrc(s)->reg.file) mask &= ~(1 << i); } for (n = 0, i = 0; this->srcExists(i); ++i, mask >>= 1) n += mask & 1; return n; }
void InstSwitch::dump(const Cfg *Func) const { Ostream &Str = Func->getContext()->getStrDump(); Type Ty = getComparison()->getType(); Str << "switch " << Ty << " "; getSrc(0)->dump(Func); Str << ", label %" << getLabelDefault()->getName() << " [\n"; for (SizeT I = 0; I < getNumCases(); ++I) { Str << " " << Ty << " " << getValue(I) << ", label %" << getLabel(I)->getName() << "\n"; } Str << " ]"; }
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() << " ]"; } }
void HTMLImageElementImp::handleMutation(events::MutationEvent mutation) { std::u16string value = mutation.getNewValue(); css::CSSStyleDeclaration style(getStyle()); switch (Intern(mutation.getAttrName().c_str())) { case Intern(u"src"): if (DocumentImp* document = getOwnerDocumentImp()) { if (request) request->abort(); else request = new(std::nothrow) HttpRequest(document->getDocumentURI()); if (request) { request->open(u"GET", getSrc()); request->setHandler(boost::bind(&HTMLImageElementImp::notify, this)); document->incrementLoadEventDelayCount(); request->send(); } else active = false; } break; // Styles case Intern(u"border"): handleMutationBorder(mutation); break; case Intern(u"height"): if (mapToDimension(value)) style.setProperty(u"height", value, u"non-css"); break; case Intern(u"hspace"): if (mapToDimension(value)) { style.setProperty(u"margin-left", value, u"non-css"); style.setProperty(u"margin-right", value, u"non-css"); } break; case Intern(u"vspace"): if (mapToDimension(value)) { style.setProperty(u"margin-top", value, u"non-css"); style.setProperty(u"margin-bottom", value, u"non-css"); } break; case Intern(u"width"): if (mapToDimension(value)) style.setProperty(u"width", value, u"non-css"); break; default: HTMLElementImp::handleMutation(mutation); break; } }
void Movie::build() { I18nShapeWidget::build(); if(getSrc().empty()) return; AC_DEBUG<<"build movie " << *this << " with src: "<<getSrc(); UnlitTexturedMaterialPtr myMaterial; if (!getShape()) { myMaterial = UnlitTexturedMaterialPtr(new UnlitTexturedMaterial()); myMaterial->setCustomHandles(_myCustomShaderValues); myMaterial->setShader(_myVertexShader, _myFragmentShader); _myShape = createCustomShape(myMaterial); //given movie textures are flipped myMaterial->getTextureUnit()->getTexture()->_mirrorFlag = true; } else { myMaterial = boost::static_pointer_cast<UnlitTexturedMaterial>(getShape()->elementList_[0]->material_); myMaterial->getTextureUnit()->getTexture()->unbind(); } masl::MovieEngineSingleton::get().getNative()->loadMovie(this, getSrc()); masl::VideoInfo myMovieInfo = masl::MovieEngineSingleton::get().getNative()->getMovieInfo(this); // inject texture name myMaterial->getTextureUnit()->getTexture()->_textureId = myMovieInfo.textureID; //TODO: add maybe video texture to wrap this preprocessor statement // define engine texture targets if (masl::MovieEngineSingleton::get().getNative()->isAvailable()) { #ifdef ANDROID myMaterial->getTextureUnit()->getTexture()->_textureTarget = GL_TEXTURE_EXTERNAL_OES; #endif } // adjust widget size vector2 myMovieSize = vector2(myMovieInfo.width, myMovieInfo.height); float myWidth = _myForcedSize[0] == -1 ? myMovieSize[0] : _myForcedSize[0]; float myHeight = _myForcedSize[1] == -1 ? myMovieSize[1] : _myForcedSize[1]; I18nShapeWidget::setSize(vector2(myWidth, myHeight)); }
// 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"); }
Instruction * Instruction::clone(ClonePolicy<Function>& pol, Instruction *i) const { if (!i) i = new_Instruction(pol.context(), op, dType); #ifndef NDEBUG // non-conformant assert, so this is required assert(typeid(*i) == typeid(*this)); #endif pol.set<Instruction>(this, i); i->sType = sType; i->rnd = rnd; i->cache = cache; i->subOp = subOp; i->saturate = saturate; i->join = join; i->exit = exit; i->mask = mask; i->ftz = ftz; i->dnz = dnz; i->ipa = ipa; i->lanes = lanes; i->perPatch = perPatch; i->postFactor = postFactor; for (int d = 0; defExists(d); ++d) i->setDef(d, pol.get(getDef(d))); for (int s = 0; srcExists(s); ++s) { i->setSrc(s, pol.get(getSrc(s))); i->src(s).mod = src(s).mod; } i->cc = cc; i->predSrc = predSrc; i->flagsDef = flagsDef; i->flagsSrc = flagsSrc; return i; }
SSATmp* TraceBuilder::preOptimizeDecRef(IRInstruction* inst) { /* * Refcount optimization: * * If the decref'ed value is guaranteed to be available after the decref, * generate DecRefNZ instead of DecRef. * * This is safe WRT copy-on-write because all the instructions that * could cause a COW return a new SSATmp that will replace the * tracked state that we are using to determine the value is still * available. I.e. by the time they get to the DecRef we won't see * it in isValueAvailable anymore and won't convert to DecRefNZ. */ auto const srcInst = inst->getSrc(0)->inst(); if (srcInst->op() == IncRef) { if (isValueAvailable(srcInst->getSrc(0))) { inst->setOpcode(DecRefNZ); } } return nullptr; }
UTF8String::operator std::string() const { return getSrc(); }
//preconditions: none //postconditions: prints out the word object //description: cout overloaded operator void word::print(void) const { cout << getSrc() << ":" << getDest() << endl; }
void Instruction::print() const { #define BUFSZ 512 const size_t size = BUFSZ; char buf[BUFSZ]; int s, d; size_t pos = 0; PRINT("%s", colour[TXT_INSN]); if (join) PRINT("join "); if (predSrc >= 0) { const size_t pre = pos; if (getSrc(predSrc)->reg.file == FILE_PREDICATE) { if (cc == CC_NOT_P) PRINT("not"); } else { PRINT("%s", CondCodeStr[cc]); } if (pos > pre) SPACE(); pos += getSrc(predSrc)->print(&buf[pos], BUFSZ - pos); PRINT(" %s", colour[TXT_INSN]); } if (saturate) PRINT("sat "); if (asFlow()) { PRINT("%s", operationStr[op]); if (asFlow()->indirect) PRINT(" ind"); if (asFlow()->absolute) PRINT(" abs"); if (op == OP_CALL && asFlow()->builtin) { PRINT(" %sBUILTIN:%i", colour[TXT_BRA], asFlow()->target.builtin); } else if (op == OP_CALL && asFlow()->target.fn) { PRINT(" %s%s:%i", colour[TXT_BRA], asFlow()->target.fn->getName(), asFlow()->target.fn->getLabel()); } else if (asFlow()->target.bb) PRINT(" %sBB:%i", colour[TXT_BRA], asFlow()->target.bb->getId()); } else { PRINT("%s ", operationStr[op]); if (op == OP_LINTERP || op == OP_PINTERP) PRINT("%s ", interpStr[ipa]); switch (op) { case OP_SUREDP: case OP_ATOM: if (subOp < ARRAY_SIZE(atomSubOpStr)) PRINT("%s ", atomSubOpStr[subOp]); break; case OP_LOAD: case OP_STORE: if (subOp < ARRAY_SIZE(ldstSubOpStr)) PRINT("%s ", ldstSubOpStr[subOp]); break; case OP_SUBFM: if (subOp < ARRAY_SIZE(subfmOpStr)) PRINT("%s ", subfmOpStr[subOp]); break; case OP_SHFL: if (subOp < ARRAY_SIZE(shflOpStr)) PRINT("%s ", shflOpStr[subOp]); break; case OP_PIXLD: if (subOp < ARRAY_SIZE(pixldOpStr)) PRINT("%s ", pixldOpStr[subOp]); break; case OP_RCP: case OP_RSQ: if (subOp < ARRAY_SIZE(rcprsqOpStr)) PRINT("%s ", rcprsqOpStr[subOp]); break; case OP_EMIT: if (subOp < ARRAY_SIZE(emitOpStr)) PRINT("%s ", emitOpStr[subOp]); break; default: if (subOp) PRINT("(SUBOP:%u) ", subOp); break; } if (perPatch) PRINT("patch "); if (asTex()) PRINT("%s %s$r%u $s%u %s", asTex()->tex.target.getName(), colour[TXT_MEM], asTex()->tex.r, asTex()->tex.s, colour[TXT_INSN]); if (postFactor) PRINT("x2^%i ", postFactor); PRINT("%s%s", dnz ? "dnz " : (ftz ? "ftz " : ""), DataTypeStr[dType]); } if (rnd != ROUND_N) PRINT(" %s", RoundModeStr[rnd]); if (defExists(1)) PRINT(" {"); for (d = 0; defExists(d); ++d) { SPACE(); pos += getDef(d)->print(&buf[pos], size - pos); } if (d > 1) PRINT(" %s}", colour[TXT_INSN]); else if (!d && !asFlow()) PRINT(" %s#", colour[TXT_INSN]); if (asCmp()) PRINT(" %s%s", colour[TXT_INSN], CondCodeStr[asCmp()->setCond]); if (sType != dType) PRINT(" %s%s", colour[TXT_INSN], DataTypeStr[sType]); for (s = 0; srcExists(s); ++s) { if (s == predSrc || src(s).usedAsPtr) continue; const size_t pre = pos; SPACE(); pos += src(s).mod.print(&buf[pos], BUFSZ - pos); if (pos > pre + 1) SPACE(); if (src(s).isIndirect(0) || src(s).isIndirect(1)) pos += getSrc(s)->asSym()->print(&buf[pos], BUFSZ - pos, getIndirect(s, 0), getIndirect(s, 1)); else pos += getSrc(s)->print(&buf[pos], BUFSZ - pos, sType); } if (exit) PRINT("%s exit", colour[TXT_INSN]); PRINT("%s", colour[TXT_DEFAULT]); buf[MIN2(pos, BUFSZ - 1)] = 0; INFO("%s (%u)\n", buf, encSize); }
void Movie::play() { AC_INFO << "playing movie: "<< getSrc() << " (volume: " << _volume <<")"; masl::MovieEngineSingleton::get().getNative()->playMovie(this); setVolume(_volume); }