Optimizer.cpp revision 8772202b4bf74c5e8e00da32edc74e147d439f49
12ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
22ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens//
32ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens// Licensed under the Apache License, Version 2.0 (the "License");
42ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens// you may not use this file except in compliance with the License.
52ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens// You may obtain a copy of the License at
62ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens//
72ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens//    http://www.apache.org/licenses/LICENSE-2.0
82ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens//
92ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens// Unless required by applicable law or agreed to in writing, software
102ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens// distributed under the License is distributed on an "AS IS" BASIS,
112ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
122ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens// See the License for the specific language governing permissions and
132ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens// limitations under the License.
142ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens
152ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens#include "Optimizer.hpp"
162ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens
172ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens#include "src/IceCfg.h"
182ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens#include "src/IceCfgNode.h"
192ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens
202ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens#include <map>
212ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens#include <vector>
222ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens
232ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capensnamespace
242ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens{
252ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens	class Optimizer
262ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens	{
272ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens	public:
282ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens		void run(Ice::Cfg *function);
292ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens
302ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens	private:
312ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens		void analyzeUses(Ice::Cfg *function);
32c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens		void eliminateDeadCode();
33f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		void eliminateUnitializedLoads();
34e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		void eliminateLoadsFollowingSingleStore();
3516252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens		void optimizeStoresInSingleBasicBlock();
36e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
37e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		void replace(Ice::Inst *instruction, Ice::Operand *newValue);
38e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		void deleteInstruction(Ice::Inst *instruction);
39c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens		bool isDead(Ice::Inst *instruction);
40f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
41709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens		static const Ice::InstIntrinsicCall *asLoadSubVector(const Ice::Inst *instruction);
42709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens		static const Ice::InstIntrinsicCall *asStoreSubVector(const Ice::Inst *instruction);
43f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		static bool isLoad(const Ice::Inst &instruction);
44f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		static bool isStore(const Ice::Inst &instruction);
45f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		static Ice::Operand *storeAddress(const Ice::Inst *instruction);
46f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		static Ice::Operand *loadAddress(const Ice::Inst *instruction);
47e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		static Ice::Operand *storeData(const Ice::Inst *instruction);
48f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens		static std::size_t storeSize(const Ice::Inst *instruction);
498772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens		static bool loadTypeMatchesStore(const Ice::Inst *load, const Ice::Inst *store);
502ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens
512ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens		Ice::Cfg *function;
52f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		Ice::GlobalContext *context;
53f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
54f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		struct Uses : std::vector<Ice::Inst*>
55f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		{
56f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			bool areOnlyLoadStore() const;
57f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			void insert(Ice::Operand *value, Ice::Inst *instruction);
58f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			void erase(Ice::Inst *instruction);
59f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
60f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			std::vector<Ice::Inst*> loads;
61f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			std::vector<Ice::Inst*> stores;
62f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		};
632ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens
64f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		std::map<Ice::Operand*, Uses> uses;
65e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		std::map<Ice::Inst*, Ice::CfgNode*> node;
66e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		std::map<Ice::Variable*, Ice::Inst*> definition;
672ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens	};
682ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens
692ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens	void Optimizer::run(Ice::Cfg *function)
702ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens	{
712ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens		this->function = function;
72f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		this->context = function->getContext();
732ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens
742ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens		analyzeUses(function);
752ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens
76c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens		eliminateDeadCode();
77f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		eliminateUnitializedLoads();
78e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		eliminateLoadsFollowingSingleStore();
7916252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens		optimizeStoresInSingleBasicBlock();
80c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens		eliminateDeadCode();
812ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens	}
822ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens
83c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens	void Optimizer::eliminateDeadCode()
842ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens	{
85c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens		bool modified;
86c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens		do
872ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens		{
88c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens			modified = false;
89c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens			for(Ice::CfgNode *basicBlock : function->getNodes())
902ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens			{
91c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens				for(Ice::Inst &inst : Ice::reverse_range(basicBlock->getInsts()))
92c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens				{
93c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens					if(inst.isDeleted())
94c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens					{
95c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens						continue;
96c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens					}
972ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens
98c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens					if(isDead(&inst))
99c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens					{
100c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens						deleteInstruction(&inst);
101c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens						modified = true;
102c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens					}
103c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens				}
1042ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens			}
1052ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens		}
106c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens		while(modified);
1072ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens	}
1082ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens
109f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	void Optimizer::eliminateUnitializedLoads()
110f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	{
111f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		Ice::CfgNode *entryBlock = function->getEntryNode();
112f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
113f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		for(Ice::Inst &alloca : entryBlock->getInsts())
114f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		{
115f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			if(alloca.isDeleted())
116f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			{
117f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens				continue;
118f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			}
119f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
120f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			if(!llvm::isa<Ice::InstAlloca>(alloca))
121f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			{
122f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens				return;   // Allocas are all at the top
123f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			}
124f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
125f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			Ice::Operand *address = alloca.getDest();
126f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			const auto &addressEntry = uses.find(address);
127f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			const auto &addressUses = addressEntry->second;
128f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
129f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			if(!addressUses.areOnlyLoadStore())
130f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			{
131f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens				continue;
132f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			}
133f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
134f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			if(addressUses.stores.empty())
135f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			{
136f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens				for(Ice::Inst *load : addressUses.loads)
137f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens				{
138f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens					Ice::Variable *loadData = load->getDest();
139f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
140f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens					for(Ice::Inst *use : uses[loadData])
141f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens					{
142113e33ac5a3455981941643df40a98243fd4469fAlexis Hetu						for(Ice::SizeT i = 0; i < use->getSrcSize(); i++)
143f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens						{
144f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens							if(use->getSrc(i) == loadData)
145f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens							{
146f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens								auto *undef = context->getConstantUndef(loadData->getType());
147f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
148f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens								use->replaceSource(i, undef);
149f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens							}
150f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens						}
151f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens					}
152f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
153f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens					uses.erase(loadData);
154f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
155f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens					load->setDeleted();
156f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens				}
157f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
158f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens				alloca.setDeleted();
159f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens				uses.erase(addressEntry);
160f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			}
161f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		}
162f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	}
163f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
164e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens	void Optimizer::eliminateLoadsFollowingSingleStore()
165e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens	{
166e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		Ice::CfgNode *entryBlock = function->getEntryNode();
167e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
168e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		for(Ice::Inst &alloca : entryBlock->getInsts())
169e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		{
170e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			if(alloca.isDeleted())
171e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			{
172e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens				continue;
173e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			}
174e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
175e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			if(!llvm::isa<Ice::InstAlloca>(alloca))
176e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			{
177e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens				return;   // Allocas are all at the top
178e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			}
179e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
180e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			Ice::Operand *address = alloca.getDest();
181e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			const auto &addressEntry = uses.find(address);
182e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			auto &addressUses = addressEntry->second;
183e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
184e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			if(!addressUses.areOnlyLoadStore())
185e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			{
186e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens				continue;
187e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			}
188e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
189e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			if(addressUses.stores.size() == 1)
190e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			{
191e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens				Ice::Inst *store = addressUses.stores[0];
192e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens				Ice::Operand *storeValue = storeData(store);
193e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
194e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens				for(Ice::Inst *load = &*++store->getIterator(), *next = nullptr; load != next; next = load, load = &*++store->getIterator())
195e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens				{
196e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					if(load->isDeleted() || !isLoad(*load))
197e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					{
198e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						continue;
199e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					}
200e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
201e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					if(loadAddress(load) != address)
202e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					{
203e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						continue;
204e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					}
205e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
2068772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens					if(!loadTypeMatchesStore(load, store))
2078772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens					{
2088772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens						continue;
2098772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens					}
2108772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens
211e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					replace(load, storeValue);
212e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
213113e33ac5a3455981941643df40a98243fd4469fAlexis Hetu					for(size_t i = 0; i < addressUses.loads.size(); i++)
214e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					{
215e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						if(addressUses.loads[i] == load)
216e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						{
217e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens							addressUses.loads[i] = addressUses.loads.back();
218e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens							addressUses.loads.pop_back();
219e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens							break;
220e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						}
221e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					}
222e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
223113e33ac5a3455981941643df40a98243fd4469fAlexis Hetu					for(size_t i = 0; i < addressUses.size(); i++)
224e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					{
225e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						if(addressUses[i] == load)
226e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						{
227e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens							addressUses[i] = addressUses.back();
228e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens							addressUses.pop_back();
229e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens							break;
230e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						}
231e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					}
232e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
233e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					if(addressUses.size() == 1)
234e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					{
235e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						assert(addressUses[0] == store);
236e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
237e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						alloca.setDeleted();
238e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						store->setDeleted();
239e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						uses.erase(address);
240e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
241e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						auto &valueUses = uses[storeValue];
242e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
243113e33ac5a3455981941643df40a98243fd4469fAlexis Hetu						for(size_t i = 0; i < valueUses.size(); i++)
244e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						{
245e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens							if(valueUses[i] == store)
246e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens							{
247e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens								valueUses[i] = valueUses.back();
248e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens								valueUses.pop_back();
249e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens								break;
250e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens							}
251e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						}
252e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
253e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						if(valueUses.empty())
254e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						{
255e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens							uses.erase(storeValue);
256e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						}
257e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
258e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						break;
259e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					}
260e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens				}
261e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			}
262e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		}
263e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens	}
264e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
26516252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens	void Optimizer::optimizeStoresInSingleBasicBlock()
26616252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens	{
26716252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens		Ice::CfgNode *entryBlock = function->getEntryNode();
26816252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens
26916252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens		for(Ice::Inst &alloca : entryBlock->getInsts())
27016252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens		{
27116252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens			if(alloca.isDeleted())
27216252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens			{
27316252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens				continue;
27416252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens			}
27516252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens
27616252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens			if(!llvm::isa<Ice::InstAlloca>(alloca))
27716252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens			{
27816252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens				return;   // Allocas are all at the top
27916252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens			}
28016252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens
28116252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens			Ice::Operand *address = alloca.getDest();
28216252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens			const auto &addressEntry = uses.find(address);
28316252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens			const auto &addressUses = addressEntry->second;
28416252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens
28516252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens			if(!addressUses.areOnlyLoadStore())
28616252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens			{
28716252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens				continue;
28816252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens			}
28916252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens
29016252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens			Ice::CfgNode *singleBasicBlock = node[addressUses.stores[0]];
29116252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens
292113e33ac5a3455981941643df40a98243fd4469fAlexis Hetu			for(size_t i = 1; i < addressUses.stores.size(); i++)
29316252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens			{
29416252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens				Ice::Inst *store = addressUses.stores[i];
29516252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens				if(node[store] != singleBasicBlock)
29616252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens				{
29716252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens					singleBasicBlock = nullptr;
29816252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens					break;
29916252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens				}
30016252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens			}
30116252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens
30216252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens			if(singleBasicBlock)
30316252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens			{
30416252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens				auto &insts = singleBasicBlock->getInsts();
30516252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens				Ice::Inst *store = nullptr;
30616252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens				Ice::Operand *storeValue = nullptr;
3078772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens				bool unmatchedLoads = false;
30816252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens
30916252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens				for(Ice::Inst &inst : insts)
31016252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens				{
31116252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens					if(inst.isDeleted())
31216252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens					{
31316252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens						continue;
31416252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens					}
31516252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens
31616252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens					if(isStore(inst))
31716252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens					{
31816252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens						if(storeAddress(&inst) != address)
31916252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens						{
32016252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens							continue;
32116252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens						}
32216252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens
323f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens						// New store found. If we had a previous one, try to eliminate it.
3248772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens						if(store && !unmatchedLoads)
32516252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens						{
326f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens							// If the previous store is wider than the new one, we can't eliminate it
327f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens							// because there could be a wide load reading its non-overwritten data.
328f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens							if(storeSize(&inst) >= storeSize(store))
329f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens							{
330f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens								deleteInstruction(store);
331f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens							}
33216252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens						}
33316252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens
33416252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens						store = &inst;
33516252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens						storeValue = storeData(store);
3368772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens						unmatchedLoads = false;
33716252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens					}
33816252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens					else if(isLoad(inst))
33916252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens					{
34016252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens						Ice::Inst *load = &inst;
34116252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens
34216252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens						if(loadAddress(load) != address)
34316252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens						{
34416252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens							continue;
34516252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens						}
34616252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens
3478772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens						if(!loadTypeMatchesStore(load, store))
34822e18bcc94c6b1220b8ea2d54bbec18539f6f33fNicolas Capens						{
3498772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens							unmatchedLoads = true;
3508772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens							continue;
35122e18bcc94c6b1220b8ea2d54bbec18539f6f33fNicolas Capens						}
3528772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens
3538772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens						replace(load, storeValue);
35416252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens					}
35516252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens				}
35616252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens			}
35716252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens		}
35816252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens	}
35916252ab6ae40e3b0938c62eedfb403abc2a02e39Nicolas Capens
3602ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens	void Optimizer::analyzeUses(Ice::Cfg *function)
3612ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens	{
3622ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens		uses.clear();
363e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		node.clear();
364e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		definition.clear();
3652ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens
3662ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens		for(Ice::CfgNode *basicBlock : function->getNodes())
3672ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens		{
3682ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens			for(Ice::Inst &instruction : basicBlock->getInsts())
3692ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens			{
3702ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens				if(instruction.isDeleted())
3712ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens				{
3722ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens					continue;
3732ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens				}
3742ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens
375e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens				node[&instruction] = basicBlock;
376e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens				definition[instruction.getDest()] = &instruction;
377e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
378113e33ac5a3455981941643df40a98243fd4469fAlexis Hetu				for(Ice::SizeT i = 0; i < instruction.getSrcSize(); i++)
3792ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens				{
380113e33ac5a3455981941643df40a98243fd4469fAlexis Hetu					Ice::SizeT unique = 0;
3812ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens					for(; unique < i; unique++)
3822ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens					{
3832ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens						if(instruction.getSrc(i) == instruction.getSrc(unique))
3842ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens						{
3852ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens							break;
3862ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens						}
3872ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens					}
3882ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens
3892ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens					if(i == unique)
3902ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens					{
391f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens						Ice::Operand *src = instruction.getSrc(i);
392f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens						uses[src].insert(src, &instruction);
3932ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens					}
3942ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens				}
3952ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens			}
3962ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens		}
3972ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens	}
398f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
399e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens	void Optimizer::replace(Ice::Inst *instruction, Ice::Operand *newValue)
400e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens	{
401e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		Ice::Variable *oldValue = instruction->getDest();
402e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
403e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		if(!newValue)
404e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		{
405e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			newValue = context->getConstantUndef(oldValue->getType());
406e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		}
407e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
408e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		for(Ice::Inst *use : uses[oldValue])
409e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		{
410e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			assert(!use->isDeleted());   // Should have been removed from uses already
411e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
412113e33ac5a3455981941643df40a98243fd4469fAlexis Hetu			for(Ice::SizeT i = 0; i < use->getSrcSize(); i++)
413e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			{
414e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens				if(use->getSrc(i) == oldValue)
415e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens				{
416e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					use->replaceSource(i, newValue);
417e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens				}
418e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			}
419e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
420e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			uses[newValue].insert(newValue, use);
421e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		}
422e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
423e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		uses.erase(oldValue);
424e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
425e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		deleteInstruction(instruction);
426e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens	}
427e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
428e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens	void Optimizer::deleteInstruction(Ice::Inst *instruction)
429e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens	{
430c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens		if(!instruction || instruction->isDeleted())
431e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		{
432e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			return;
433e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		}
434e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
435e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		instruction->setDeleted();
436e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
437113e33ac5a3455981941643df40a98243fd4469fAlexis Hetu		for(Ice::SizeT i = 0; i < instruction->getSrcSize(); i++)
438e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		{
439e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			Ice::Operand *src = instruction->getSrc(i);
440e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
441e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			const auto &srcEntry = uses.find(src);
442e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
443e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			if(srcEntry != uses.end())
444e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			{
445e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens				auto &srcUses = srcEntry->second;
446e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
447e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens				srcUses.erase(instruction);
448e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
449e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens				if(srcUses.empty())
450e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens				{
451e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					uses.erase(srcEntry);
452e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
453e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					if(Ice::Variable *var = llvm::dyn_cast<Ice::Variable>(src))
454e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					{
455e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens						deleteInstruction(definition[var]);
456e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens					}
457e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens				}
458e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			}
459e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		}
460e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens	}
461e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
462c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens	bool Optimizer::isDead(Ice::Inst *instruction)
463c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens	{
464c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens		Ice::Variable *dest = instruction->getDest();
465c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens
466c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens		if(dest)
467c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens		{
468c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens			return uses[dest].empty() && !instruction->hasSideEffects();
469c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens		}
470c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens		else if(isStore(*instruction))
471c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens		{
472c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens			if(Ice::Variable *address = llvm::dyn_cast<Ice::Variable>(storeAddress(instruction)))
473c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens			{
474c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens				Ice::Inst *def = definition[address];
475c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens
476da721421c80af0d542a9bde6987fef0b8106d74fNicolas Capens				if(def && llvm::isa<Ice::InstAlloca>(def))
477c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens				{
47829eee71771485fb93fde1c535e8be5c831e7943aNicolas Capens					return uses[address].size() == uses[address].stores.size();   // Dead if all uses are stores
479c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens				}
480c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens			}
481c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens		}
482c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens
483c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens		return false;
484c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens	}
485c9d70d5406b5cfb34e4c5485809bf3377d7bb6a6Nicolas Capens
486709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens	const Ice::InstIntrinsicCall *Optimizer::asLoadSubVector(const Ice::Inst *instruction)
487f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	{
488709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens		if(auto *instrinsic = llvm::dyn_cast<Ice::InstIntrinsicCall>(instruction))
489f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		{
490709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens			if(instrinsic->getIntrinsicInfo().ID == Ice::Intrinsics::LoadSubVector)
491709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens			{
492709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens				return instrinsic;
493709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens			}
494f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		}
495f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
496709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens		return nullptr;
497709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens	}
498709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens
499709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens	const Ice::InstIntrinsicCall *Optimizer::asStoreSubVector(const Ice::Inst *instruction)
500709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens	{
501709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens		if(auto *instrinsic = llvm::dyn_cast<Ice::InstIntrinsicCall>(instruction))
502f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		{
503709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens			if(instrinsic->getIntrinsicInfo().ID == Ice::Intrinsics::StoreSubVector)
504709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens			{
505709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens				return instrinsic;
506709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens			}
507f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		}
508f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
509709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens		return nullptr;
510f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	}
511f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
512709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens	bool Optimizer::isLoad(const Ice::Inst &instruction)
513f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	{
514709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens		if(llvm::isa<Ice::InstLoad>(&instruction))
515f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		{
516f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			return true;
517f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		}
518f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
519709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens		return asLoadSubVector(&instruction) != nullptr;
520709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens	}
521709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens
522709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens	bool Optimizer::isStore(const Ice::Inst &instruction)
523709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens	{
524709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens		if(llvm::isa<Ice::InstStore>(&instruction))
525f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		{
526709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens			return true;
527f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		}
528f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
529709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens		return asStoreSubVector(&instruction) != nullptr;
530f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	}
531f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
532f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	Ice::Operand *Optimizer::storeAddress(const Ice::Inst *instruction)
533f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	{
534f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		assert(isStore(*instruction));
535f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
536f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		if(auto *store = llvm::dyn_cast<Ice::InstStore>(instruction))
537f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		{
538f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			return store->getAddr();
539f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		}
540f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
541709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens		if(auto *storeSubVector = asStoreSubVector(instruction))
542f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		{
543709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens			return storeSubVector->getSrc(2);
544f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		}
545f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
546f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		return nullptr;
547f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	}
548f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
549f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	Ice::Operand *Optimizer::loadAddress(const Ice::Inst *instruction)
550f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	{
551f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		assert(isLoad(*instruction));
552f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
553f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		if(auto *load = llvm::dyn_cast<Ice::InstLoad>(instruction))
554f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		{
555f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			return load->getSourceAddress();
556f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		}
557f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
558709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens		if(auto *loadSubVector = asLoadSubVector(instruction))
559f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		{
560709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens			return loadSubVector->getSrc(1);
561f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		}
562f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
563f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		return nullptr;
564f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	}
565f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
566e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens	Ice::Operand *Optimizer::storeData(const Ice::Inst *instruction)
567e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens	{
568e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		assert(isStore(*instruction));
569e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
570e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		if(auto *store = llvm::dyn_cast<Ice::InstStore>(instruction))
571e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		{
572e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens			return store->getData();
573e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		}
574e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
575709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens		if(auto *storeSubVector = asStoreSubVector(instruction))
576e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		{
577709f69b2fc94c0d42f1df587703123dc0a37a8e9Nicolas Capens			return storeSubVector->getSrc(1);
578e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		}
579e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
580e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens		return nullptr;
581e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens	}
582e205c3d63c887ccfe0fa217797e97c25e0e9aa35Nicolas Capens
583f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens	std::size_t Optimizer::storeSize(const Ice::Inst *store)
584f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens	{
585f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens		assert(isStore(*store));
586f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens
587f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens		if(auto *instStore = llvm::dyn_cast<Ice::InstStore>(store))
588f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens		{
589f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens			return Ice::typeWidthInBytes(instStore->getData()->getType());
590f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens		}
591f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens
592f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens		if(auto *storeSubVector = asStoreSubVector(store))
593f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens		{
594f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens			return llvm::cast<Ice::ConstantInteger32>(storeSubVector->getSrc(3))->getValue();
595f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens		}
596f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens
597f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens		return 0;
598f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens	}
599f2f5e962823401ee7a56979e18f0ed37b7bc91c5Nicolas Capens
6008772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens	bool Optimizer::loadTypeMatchesStore(const Ice::Inst *load, const Ice::Inst *store)
6018772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens	{
6028772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens		if(!load || !store)
6038772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens		{
6048772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens			return false;
6058772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens		}
6068772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens
6078772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens		assert(isLoad(*load) && isStore(*store));
6088772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens		assert(loadAddress(load) == storeAddress(store));
6098772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens
6108772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens		if(auto *instStore = llvm::dyn_cast<Ice::InstStore>(store))
6118772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens		{
6128772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens			if(auto *instLoad = llvm::dyn_cast<Ice::InstLoad>(load))
6138772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens			{
6148772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens				return instStore->getData()->getType() == instLoad->getDest()->getType();
6158772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens			}
6168772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens		}
6178772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens
6188772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens		if(auto *storeSubVector = asStoreSubVector(store))
6198772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens		{
6208772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens			if(auto *loadSubVector = asLoadSubVector(load))
6218772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens			{
6228772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens				// Check for matching type and sub-vector width.
6238772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens				return storeSubVector->getSrc(1)->getType() == loadSubVector->getDest()->getType() &&
6248772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens				       llvm::cast<Ice::ConstantInteger32>(storeSubVector->getSrc(3))->getValue() ==
6258772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens				       llvm::cast<Ice::ConstantInteger32>(loadSubVector->getSrc(2))->getValue();
6268772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens			}
6278772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens		}
6288772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens
6298772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens		return false;
6308772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens	}
6318772202b4bf74c5e8e00da32edc74e147d439f49Nicolas Capens
632f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	bool Optimizer::Uses::areOnlyLoadStore() const
633f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	{
634f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		return size() == (loads.size() + stores.size());
635f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	}
636f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
637f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	void Optimizer::Uses::insert(Ice::Operand *value, Ice::Inst *instruction)
638f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	{
639f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		push_back(instruction);
640f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
641f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		if(isLoad(*instruction))
642f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		{
643f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			if(value == loadAddress(instruction))
644f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			{
645f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens				loads.push_back(instruction);
646f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			}
647f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		}
648f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		else if(isStore(*instruction))
649f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		{
650f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			if(value == storeAddress(instruction))
651f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			{
652f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens				stores.push_back(instruction);
653f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			}
654f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		}
655f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	}
656f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
657f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	void Optimizer::Uses::erase(Ice::Inst *instruction)
658f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	{
659f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		auto &uses = *this;
660f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
661113e33ac5a3455981941643df40a98243fd4469fAlexis Hetu		for(size_t i = 0; i < uses.size(); i++)
662f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		{
663f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			if(uses[i] == instruction)
664f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			{
665f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens				uses[i] = back();
666f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens				pop_back();
667f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
668113e33ac5a3455981941643df40a98243fd4469fAlexis Hetu				for(size_t i = 0; i < loads.size(); i++)
669f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens				{
670f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens					if(loads[i] == instruction)
671f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens					{
672f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens						loads[i] = loads.back();
673f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens						loads.pop_back();
674f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens						break;
675f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens					}
676f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens				}
677f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
678113e33ac5a3455981941643df40a98243fd4469fAlexis Hetu				for(size_t i = 0; i < stores.size(); i++)
679f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens				{
680f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens					if(stores[i] == instruction)
681f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens					{
682f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens						stores[i] = stores.back();
683f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens						stores.pop_back();
684f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens						break;
685f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens					}
686f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens				}
687f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens
688f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens				break;
689f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens			}
690f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens		}
691f4452fc4a4f72009441abf978e2ce92ef8d42ffbNicolas Capens	}
6922ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens}
6932ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens
6942ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capensnamespace sw
6952ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens{
6962ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens	void optimize(Ice::Cfg *function)
6972ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens	{
6982ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens		Optimizer optimizer;
6992ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens
7002ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens		optimizer.run(function);
7012ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens	}
7022ae9d748de3749956aefad727fa9fdab4eb8eef2Nicolas Capens}