bool LocalAccessChainConvertPass::ConvertLocalAccessChains(ir::Function* func) { FindTargetVars(func); // Replace access chains of all targeted variables with equivalent // extract and insert sequences bool modified = false; for (auto bi = func->begin(); bi != func->end(); ++bi) { for (auto ii = bi->begin(); ii != bi->end(); ++ii) { switch (ii->opcode()) { case SpvOpLoad: { uint32_t varId; ir::Instruction* ptrInst = GetPtr(&*ii, &varId); if (!IsNonPtrAccessChain(ptrInst->opcode())) break; if (!IsTargetVar(varId)) break; std::vector<std::unique_ptr<ir::Instruction>> newInsts; uint32_t replId = GenAccessChainLoadReplacement(ptrInst, &newInsts); ReplaceAndDeleteLoad(&*ii, replId); ++ii; ii = ii.InsertBefore(&newInsts); ++ii; modified = true; } break; case SpvOpStore: { uint32_t varId; ir::Instruction* ptrInst = GetPtr(&*ii, &varId); if (!IsNonPtrAccessChain(ptrInst->opcode())) break; if (!IsTargetVar(varId)) break; std::vector<std::unique_ptr<ir::Instruction>> newInsts; uint32_t valId = ii->GetSingleWordInOperand(kStoreValIdInIdx); GenAccessChainStoreReplacement(ptrInst, valId, &newInsts); def_use_mgr_->KillInst(&*ii); DeleteIfUseless(ptrInst); ++ii; ii = ii.InsertBefore(&newInsts); ++ii; ++ii; modified = true; } break; default: break; } } } return modified; }
DOCKPANEL * NewDockPanel(DOCKSERVER *dsp) { DOCKPANEL *dpp; // Allocate a DOCKPANEL and insert into the main PanelList if((dpp = AllocDockObj(0, 0, NextId(dsp), sizeof(DOCKPANEL))) == 0) return 0; InsertBefore(dpp, dsp->PanelListTail); // intialise the DOCKPANEL's WndList dpp->WndListHead = AllocDockObj(0, 0, -1, sizeof(DOCKWND)); dpp->WndListTail = AllocDockObj(0, 0, -2, sizeof(DOCKWND)); dpp->WndListHead->flink = dpp->WndListTail; dpp->WndListTail->blink = dpp->WndListHead; SetRect(&dpp->rcDockBorder, DEFAULT_BORDER, DEFAULT_BORDER, DEFAULT_BORDER, DEFAULT_BORDER); SetRect(&dpp->rcFloatBorder, 0, DEFAULT_BORDER, 0, 0); dpp->hwndMain = dsp->hwndMain; dpp->uCurrentTabId = 0; dpp->FloatSize.cx = 0; dpp->FloatSize.cy = 0; dpp->DockSize.cx = 0; dpp->DockSize.cy = 0; dpp->dwStyle = 0; dpp->xpos = 0; dpp->ypos = 0; dpp->pDockServer = dsp; return dpp; }
bool CommonUniformElimPass::UniformAccessChainConvert(ir::Function* func) { bool modified = false; for (auto bi = func->begin(); bi != func->end(); ++bi) { for (auto ii = bi->begin(); ii != bi->end(); ++ii) { if (ii->opcode() != SpvOpLoad) continue; uint32_t varId; ir::Instruction* ptrInst = GetPtr(&*ii, &varId); if (!IsNonPtrAccessChain(ptrInst->opcode())) continue; // Do not convert nested access chains if (ptrInst->GetSingleWordInOperand(kAccessChainPtrIdInIdx) != varId) continue; if (!IsUniformVar(varId)) continue; if (!IsConstantIndexAccessChain(ptrInst)) continue; if (HasUnsupportedDecorates(ii->result_id())) continue; if (HasUnsupportedDecorates(ptrInst->result_id())) continue; std::vector<std::unique_ptr<ir::Instruction>> newInsts; uint32_t replId; GenACLoadRepl(ptrInst, &newInsts, &replId); ReplaceAndDeleteLoad(&*ii, replId, ptrInst); ++ii; ii = ii.InsertBefore(&newInsts); ++ii; modified = true; } } return modified; }
void OverrideList::AddHead( OverrideListItem* poliToAdd) { if (poliToAdd==NULL) { ERROR2RAW("OverrideList::AddHead - NULL parameter"); return; } //Get the first item in the list OverrideListItem* pliFirst=(OverrideListItem*) GetHead(); //Was there anything in the list? if (pliFirst!=NULL) { //Yes. So call our InsertBefore function InsertBefore(pliFirst, poliToAdd); } else { //No. So we need do no special checking - simply insert //the list item List::AddHead(poliToAdd); } }
/*********************************************************************************** ** ** TreeViewModel::OnItemAdded ** ***********************************************************************************/ void TreeViewModel::OnItemAdded(OpTreeModel* tree_model, INT32 index) { TreeViewModelItem* item = OP_NEW(TreeViewModelItem, (m_model->GetItemByPosition(index))); if (!item) return; if (GetSortListener()) { INT32 parent = GetIndexByModelIndex(m_model->GetItemParent(index)); if (parent == -1 && GetTreeModelGrouping() && GetTreeModelGrouping()->HasGrouping()) { parent = static_cast<TreeViewModelItem*>(GetTreeModelGrouping()->GetGroupHeader(GetTreeModelGrouping()->GetGroupForItem(item)))->GetIndex(); } AddSorted(item, parent); } else { INT32 parent = m_model->GetItemParent(index); if (index < GetCount() && GetParentIndex(index) == parent) { InsertBefore(item, index); } else { AddLast(item, parent); } } }
/* Inserts a node at the nTH position */ wyElem* List::InsertBefore(wyUInt32 nbefore, wyElem* pelem) { wyUInt32 i; wyElem* elempointer; VERIFY(m_first); // if the user wants to add in the first position if(nbefore == 0){ m_first->m_prev = pelem; pelem->m_next = m_first->m_next; m_first = pelem; return pelem; } // If the user wants to add at the last. if(nbefore>(m_elemcount-1)) return Insert(pelem); // traverse thru the list and add it. i=0; elempointer=m_first; while(i<nbefore) { elempointer=elempointer->m_next; i++; } //for(i=0, elempointer=m_first; i<nbefore ; i++, elempointer=elempointer->m_next); return InsertBefore(elempointer, pelem); }
// XXX: What if instead of split, we just deleted the unneeded children of // mRight and re-inserted mLeft? NS_IMETHODIMP JoinNodeTransaction::UndoTransaction() { if (NS_WARN_IF(!mParent) || NS_WARN_IF(!mLeftNode) || NS_WARN_IF(!mRightNode)) { return NS_ERROR_NOT_INITIALIZED; } // First, massage the existing node so it is in its post-split state ErrorResult rv; if (mRightNode->GetAsText()) { mRightNode->GetAsText()->DeleteData(0, mOffset, rv); if (rv.Failed()) { return rv.StealNSResult(); } } else { nsCOMPtr<nsIContent> child = mRightNode->GetFirstChild(); for (uint32_t i = 0; i < mOffset; i++) { if (rv.Failed()) { return rv.StealNSResult(); } if (!child) { return NS_ERROR_NULL_POINTER; } nsCOMPtr<nsIContent> nextSibling = child->GetNextSibling(); mLeftNode->AppendChild(*child, rv); child = nextSibling; } } // Second, re-insert the left node into the tree nsCOMPtr<nsINode> refNode = mRightNode; mParent->InsertBefore(*mLeftNode, refNode, rv); return rv.StealNSResult(); }
void *addItemToList(tList *pList, void *pItem, int(*fcmp)(void *pItList, void *pItNew)) { if(pItem) { if(pList->phead) { pList->pcurr=pList->phead; while(pList->pcurr) { if(fcmp(pList->pcurr->pdata, pItem) > 0) { InsertBefore(pList, pItem); break; } else if(pList->pcurr == pList->ptail) { InsertTail(pList, pItem); break; } GetNext(pList); } } else InsertHead(pList, pItem); } return 0; }
LISTPOS OverrideList::InsertBefore(LISTPOS here, OverrideListItem* item) { ERROR2IF(item==NULL, NULL, "OverrideList::InsertBefore - NULL parameter"); //First find the list item at the position we have been given OverrideListItem* pliInsertionPoint=(OverrideListItem*) FindItem(here); //If we have not found it, return -1 if (pliInsertionPoint==NULL) return -1; //Otherwise, call our other function to do the insertion OverrideListItem* pliResult=(OverrideListItem*) InsertBefore(pliInsertionPoint, item); //If we have been returned NULL, then return an error value if (pliResult==NULL) return -1; //Otherwise, find our newly returned list item in the list //and return it return FindPosition(pliResult); }
AL_PROTO ALEntry::ALEntry( ALEntryList &list, ALStorage *object, ALCompressionEngine *engine ) : mrList( list ) // Initialize our own pointer to the list we will // be a member of. { mpNextItem = this; mpPreviousItem = this; mpStorageObject = object; mpCompressionEngine = engine; mlCompressedSize = -1; mlCompressedObjectPosition = -1; miMark = 1; //Always construct with the mark turned on mszComment = 0; // // I check for the object member to be non-zero because of a clunky design // choice I made a while back. Each ALEntryList has an ALEntry member that // points to the first and last members of the list. I could have (and // probably should have) made the root of the list just be a pair of pointers, // instead of a dummy ALEntry. Anyway, I can tell that dummy entry apart // from the valid entries by virtue of the fact that it has a null // pointer in its object pointer. // // So anyway, when I create this dummy object, I don't want to try to add // it to the list, because by definition it is already in the list. So // I do a check before adding any ALEntry to the list. // if ( object ) InsertBefore( *list.mpListHead ); }
void APICALL DOMParserImpl::ParseWithSpecificAction( const char * buffer, sizet bufferLength, eActionType actionType, spINode & node ) { auto parsedNode = ParseAsNode( buffer, bufferLength ); if ( parsedNode ) { switch ( actionType ) { case kATAppendAsChildren: AppendAsChildren( node, parsedNode ); break; case kATReplaceChildren: ReplaceChildren( node, parsedNode ); break; case kATAppendOrReplaceChildren: AppendOrReplaceChildren( node, parsedNode ); break; case kATInsertBefore: InsertBefore( node, parsedNode ); break; case kATInsertAfter: InsertAfter( node, parsedNode ); break; case kATReplace: ReplaceNode( node, parsedNode ); break; default: NOTIFY_ERROR( IError::kEDGeneral, kGECNotImplemented, "Not yet implemented", IError::kESOperationFatal, true, static_cast< sizet >( actionType ) ); } } }
void MTnode::SortEntries () { int n = NumEntries (); MTentry **array = new MTentry *[n], *objEntry = NULL; for (int i=0; i<n; i++) { array[i] = (MTentry *) ((MTentry *)(*this)[i].Ptr())->Copy(); if (&((MTentry *)(*this)[i].Ptr())->object() == obj) { objEntry = array[i]; } } qsort (array, n, sizeof(MTentry *), MTentryCmp); while (NumEntries() > 0) { DeleteEntry (0); // also delete the obj } int obji = -1; for (int i=0; i<n; i++) { InsertBefore (*(array[i]), i); if (array[i] == objEntry) { obji = i; } delete array[i]; } delete []array; if (obji >= 0) { obj = &((MTentry *)(*this)[obji].Ptr())->object(); } }
void IFXKeyTrack::InsertNewKeyFrame(F32 time,const IFXInstant &instant, IFXListContext *context) { IFXKeyFrame *newframe=NULL; if(context==NULL) context=&m_current; Sync(time,context); #if IFXKT_REPLACE_SAMETIME IFXListContext *context2=context; IFXKeyFrame *prior=PreDecrement(*context2); context2=context; IFXKeyFrame *next=PreIncrement(*context2); if(prior && (time-prior->Time() < IFXKT_REPLACE_DELTA) ) { IFXTRACE_GENERIC(L"InsertNewKeyFrame(time=%.6G) replacing adjacent time %.6G\n", time,prior->Time()); newframe=prior; } else if(next && (next->Time()-time < IFXKT_REPLACE_DELTA) ) { IFXTRACE_GENERIC(L"InsertNewKeyFrame(time=%.6G) replacing adjacent time %.6G\n", time,next->Time()); newframe=next; } else #endif InsertBefore(*context,newframe=new IFXKeyFrame); newframe->IFXInstant::operator=(instant); newframe->SetTime(time); }
NS_IMETHODIMP nsHTMLTableRowElement::InsertCell(PRInt32 aIndex, nsIDOMHTMLElement** aValue) { *aValue = nsnull; if (aIndex < -1) { return NS_ERROR_DOM_INDEX_SIZE_ERR; } // Make sure mCells is initialized. nsCOMPtr<nsIDOMHTMLCollection> cells; nsresult rv = GetCells(getter_AddRefs(cells)); if (NS_FAILED(rv)) { return rv; } NS_ASSERTION(mCells, "How did that happen?"); nsCOMPtr<nsIDOMNode> nextSibling; // -1 means append, so should use null nextSibling if (aIndex != -1) { cells->Item(aIndex, getter_AddRefs(nextSibling)); // Check whether we're inserting past end of list. We want to avoid doing // this unless we really have to, since this has to walk all our kids. If // we have a nextSibling, we're clearly not past end of list. if (!nextSibling) { PRUint32 cellCount; cells->GetLength(&cellCount); if (aIndex > PRInt32(cellCount)) { return NS_ERROR_DOM_INDEX_SIZE_ERR; } } } // create the cell nsCOMPtr<nsINodeInfo> nodeInfo; nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::td, getter_AddRefs(nodeInfo)); nsCOMPtr<nsIContent> cellContent = NS_NewHTMLTableCellElement(nodeInfo.forget()); if (!cellContent) { return NS_ERROR_OUT_OF_MEMORY; } nsCOMPtr<nsIDOMNode> cellNode(do_QueryInterface(cellContent)); NS_ASSERTION(cellNode, "Should implement nsIDOMNode!"); nsCOMPtr<nsIDOMNode> retChild; InsertBefore(cellNode, nextSibling, getter_AddRefs(retChild)); if (retChild) { CallQueryInterface(retChild, aValue); } return NS_OK; }
void GiSTnode::Coalesce (const GiSTnode &source) { // Coalesce by one-by-one insertion // Take each entry from the source node // and insert it into this node. for (int i=0; i<source.numEntries; i++) { // GiSTentry& e=source[i]; // this is deleted by myself InsertBefore ((GiSTentry&)source[i], NumEntries()); } }
void GiSTnode::Insert(const GiSTentry& entry) { // Find out where to insert it int i; for (i=0; i<NumEntries(); i++) if ((*this)[i]->Compare(entry) > 0) break; // Do the deed InsertBefore(entry, i); }
NS_IMETHODIMP nsHTMLTableSectionElement::InsertRow(PRInt32 aIndex, nsIDOMHTMLElement** aValue) { *aValue = nsnull; if (aIndex < -1) { return NS_ERROR_DOM_INDEX_SIZE_ERR; } nsCOMPtr<nsIDOMHTMLCollection> rows; GetRows(getter_AddRefs(rows)); PRUint32 rowCount; rows->GetLength(&rowCount); if (aIndex > (PRInt32)rowCount) { return NS_ERROR_DOM_INDEX_SIZE_ERR; } PRBool doInsert = (aIndex < PRInt32(rowCount)) && (aIndex != -1); // create the row nsCOMPtr<nsINodeInfo> nodeInfo; nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::tr, getter_AddRefs(nodeInfo)); nsCOMPtr<nsIContent> rowContent = NS_NewHTMLTableRowElement(nodeInfo); if (!nodeInfo) { return NS_ERROR_OUT_OF_MEMORY; } nsCOMPtr<nsIDOMNode> rowNode(do_QueryInterface(rowContent)); NS_ASSERTION(rowNode, "Should implement nsIDOMNode!"); nsCOMPtr<nsIDOMNode> retChild; nsresult rv; if (doInsert) { nsCOMPtr<nsIDOMNode> refRow; rows->Item(aIndex, getter_AddRefs(refRow)); rv = InsertBefore(rowNode, refRow, getter_AddRefs(retChild)); } else { rv = AppendChild(rowNode, getter_AddRefs(retChild)); } if (retChild) { CallQueryInterface(retChild, aValue); } return NS_OK; }
bool LocalAccessChainConvertPass::ConvertLocalAccessChains(Function* func) { FindTargetVars(func); // Replace access chains of all targeted variables with equivalent // extract and insert sequences bool modified = false; for (auto bi = func->begin(); bi != func->end(); ++bi) { std::vector<Instruction*> dead_instructions; for (auto ii = bi->begin(); ii != bi->end(); ++ii) { switch (ii->opcode()) { case SpvOpLoad: { uint32_t varId; Instruction* ptrInst = GetPtr(&*ii, &varId); if (!IsNonPtrAccessChain(ptrInst->opcode())) break; if (!IsTargetVar(varId)) break; std::vector<std::unique_ptr<Instruction>> newInsts; ReplaceAccessChainLoad(ptrInst, &*ii); modified = true; } break; case SpvOpStore: { uint32_t varId; Instruction* ptrInst = GetPtr(&*ii, &varId); if (!IsNonPtrAccessChain(ptrInst->opcode())) break; if (!IsTargetVar(varId)) break; std::vector<std::unique_ptr<Instruction>> newInsts; uint32_t valId = ii->GetSingleWordInOperand(kStoreValIdInIdx); GenAccessChainStoreReplacement(ptrInst, valId, &newInsts); dead_instructions.push_back(&*ii); ++ii; ii = ii.InsertBefore(std::move(newInsts)); ++ii; ++ii; modified = true; } break; default: break; } } while (!dead_instructions.empty()) { Instruction* inst = dead_instructions.back(); dead_instructions.pop_back(); DCEInst(inst, [&dead_instructions](Instruction* other_inst) { auto i = std::find(dead_instructions.begin(), dead_instructions.end(), other_inst); if (i != dead_instructions.end()) { dead_instructions.erase(i); } }); } } return modified; }
void GiSTnode::Coalesce(const GiSTnode &source, const GiSTentry& entry) // entry is the entry in the // parent node that points to this { // Coalesce by one-by-one insertion // Take each entry from the source node // and insert it into this node. for (int i=0; i<source.numEntries; i++) { GiSTentry& e = source[i]; InsertBefore(e, NumEntries()); } }
BasicBlock* Function::InsertBasicBlockAfter( std::unique_ptr<BasicBlock>&& new_block, BasicBlock* position) { for (auto bb_iter = begin(); bb_iter != end(); ++bb_iter) { if (&*bb_iter == position) { new_block->SetParent(this); ++bb_iter; bb_iter = bb_iter.InsertBefore(std::move(new_block)); return &*bb_iter; } } assert(false && "Could not find insertion point."); return nullptr; }
inline void GAExpressionLib::List< Data, DataManager >::CopyBefore( Node* node, const List* list ) { if( !node ) node = head; if( node && node->list != this ) return; for( const Node* otherNode = list->tail; otherNode; otherNode = otherNode->Prev() ) { node = InsertBefore( node ); DataManager::Copy( node->data, otherNode->data ); } }
void SetDockPanel(DOCKPANEL *dpp, DOCKWND *dwp) { DOCKPANEL *dppOld = dwp->pDockPanel; // remove the DOCKWND from it's current DOCKPANEL RemoveObj(dwp); // insert it into the new one! InsertBefore(dwp, dpp->WndListTail); dwp->pDockPanel = dpp; SetParent(dwp->hwndContents, dpp->hwndPanel); }
inline void GAExpressionLib::List< Data, DataManager >::AbsorbBefore( Node* node, List* list ) { if( !node ) node = head; if( node && node->list != this ) return; while( list->count > 0 ) { Node* otherNode = list->tail; list->Remove( otherNode, false ); node = InsertBefore( node, otherNode ); } }
LIterator LStrList::InsertBefore(__in LIterator it, __in PCWSTR lpString) { LIterator ret = NULL; LAutoLock al(m_lock); if (IsUnicode()) { ret = LPtrList::InsertBefore(it, &lpString); } else { LStringA str = lpString; ret = InsertBefore(it, str); } return ret; }
void SrcLineList::insertAt(const int idx, const CString & line, int bold, int number, int d) { SrcLine * p = new SrcLine(line, bold, number, d); POSITION pos; int lctr = 0; for(pos = GetHeadPosition() ; pos != NULL && lctr++ != idx ; GetNext(pos) ) {} if (pos) { InsertBefore(pos, p); } else { AddTail(p); } }
bool CommonUniformElimPass::CommonExtractElimination(ir::Function* func) { // Find all composite ids with duplicate extracts. for (auto bi = func->begin(); bi != func->end(); ++bi) { for (auto ii = bi->begin(); ii != bi->end(); ++ii) { if (ii->opcode() != SpvOpCompositeExtract) continue; // TODO(greg-lunarg): Support multiple indices if (ii->NumInOperands() > 2) continue; if (HasUnsupportedDecorates(ii->result_id())) continue; uint32_t compId = ii->GetSingleWordInOperand(kExtractCompositeIdInIdx); uint32_t idx = ii->GetSingleWordInOperand(kExtractIdx0InIdx); comp2idx2inst_[compId][idx].push_back(&*ii); } } // For all defs of ids with duplicate extracts, insert new extracts // after def, and replace and delete old extracts bool modified = false; for (auto bi = func->begin(); bi != func->end(); ++bi) { for (auto ii = bi->begin(); ii != bi->end(); ++ii) { const auto cItr = comp2idx2inst_.find(ii->result_id()); if (cItr == comp2idx2inst_.end()) continue; for (auto idxItr : cItr->second) { if (idxItr.second.size() < 2) continue; uint32_t replId = TakeNextId(); std::unique_ptr<ir::Instruction> newExtract(new ir::Instruction(*idxItr.second.front())); newExtract->SetResultId(replId); def_use_mgr_->AnalyzeInstDefUse(&*newExtract); ++ii; ii = ii.InsertBefore(std::move(newExtract)); for (auto instItr : idxItr.second) { uint32_t resId = instItr->result_id(); KillNamesAndDecorates(resId); (void)def_use_mgr_->ReplaceAllUsesWith(resId, replId); def_use_mgr_->KillInst(instItr); } modified = true; } } } return modified; }
// quick-sort the entries with respect to the distance from the parent void MTnode::Order() { int i, obji=-1, n=NumEntries(); MTentry **array=new MTentry *[n], *objEntry=NULL; for(i=0; i<n; i++) { array[i]=(MTentry *)((MTentry *)(*this)[i].Ptr())->Copy(); if(obj==&((MTentry *)(*this)[i].Ptr())->object()) objEntry=array[i]; } qsort(array, n, sizeof(MTentry *), MTentrycmp); while(NumEntries()>0) DeleteEntry(0); for(i=0; i<n; i++) { InsertBefore(*(array[i]), i); if(objEntry==array[i]) obji=i; delete array[i]; } delete []array; if(obji>=0) obj=&((MTentry *)(*this)[obji].Ptr())->object(); }
inline int GAExpressionLib::List< Data, DataManager >::Sort( SortCompareFunc sortCompareFunc /*= nullptr*/ ) { int adjacentSwapCount = 0; bool inOrder; do { inOrder = true; Node* nodeA = head; while( nodeA ) { int result = 0; Node* nodeB = nodeA->next; if( nodeB ) { if( sortCompareFunc ) result = sortCompareFunc( nodeA->data, nodeB->data ); else result = DataManager::Compare( nodeA->data, nodeB->data ); } if( result <= 0 ) nodeA = nodeB; else { Remove( nodeB, false ); InsertBefore( nodeA, nodeB ); inOrder = false; adjacentSwapCount++; } } } while( !inOrder ); return adjacentSwapCount; }
bool CommonUniformElimPass::CommonUniformLoadElimination(ir::Function* func) { // Process all blocks in structured order. This is just one way (the // simplest?) to keep track of the most recent block outside of control // flow, used to copy common instructions, guaranteed to dominate all // following load sites. std::list<ir::BasicBlock*> structuredOrder; ComputeStructuredOrder(func, &structuredOrder); uniform2load_id_.clear(); bool modified = false; // Find insertion point in first block to copy non-dominating loads. auto insertItr = func->begin()->begin(); while (insertItr->opcode() == SpvOpVariable || insertItr->opcode() == SpvOpNop) ++insertItr; uint32_t mergeBlockId = 0; for (auto bi = structuredOrder.begin(); bi != structuredOrder.end(); ++bi) { ir::BasicBlock* bp = *bi; // Check if we are exiting outermost control construct. If so, remember // new load insertion point. Trying to keep register pressure down. if (mergeBlockId == bp->id()) { mergeBlockId = 0; insertItr = bp->begin(); } for (auto ii = bp->begin(); ii != bp->end(); ++ii) { if (ii->opcode() != SpvOpLoad) continue; uint32_t varId; ir::Instruction* ptrInst = GetPtr(&*ii, &varId); if (ptrInst->opcode() != SpvOpVariable) continue; if (!IsUniformVar(varId)) continue; if (IsSamplerOrImageVar(varId)) continue; if (HasUnsupportedDecorates(ii->result_id())) continue; uint32_t replId; const auto uItr = uniform2load_id_.find(varId); if (uItr != uniform2load_id_.end()) { replId = uItr->second; } else { if (mergeBlockId == 0) { // Load is in dominating block; just remember it uniform2load_id_[varId] = ii->result_id(); continue; } else { // Copy load into most recent dominating block and remember it replId = TakeNextId(); std::unique_ptr<ir::Instruction> newLoad(new ir::Instruction(SpvOpLoad, ii->type_id(), replId, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {varId}}})); def_use_mgr_->AnalyzeInstDefUse(&*newLoad); insertItr = insertItr.InsertBefore(std::move(newLoad)); ++insertItr; uniform2load_id_[varId] = replId; } } ReplaceAndDeleteLoad(&*ii, replId, ptrInst); modified = true; } // If we are outside of any control construct and entering one, remember // the id of the merge block if (mergeBlockId == 0) { uint32_t dummy; mergeBlockId = MergeBlockIdIfAny(*bp, &dummy); } } return modified; }
void InsertAtEnd(int nValue) { InsertBefore(nValue, m_nLength); }