external/swiftshader
Révision | a5ac650d2031ef1ccdd4d35aa8fb57d1b55dbee9 (tree) |
---|---|
l'heure | 2018-06-15 02:24:58 |
Auteur | Alexis Hetu <sugoi@goog...> |
Commiter | Alexis Hétu |
Optimizer optimization
Optimizer::optimizeStoresInSingleBasicBlock() was taking an extremely long time due to
looping through all the instructions of a single basic block at every iteration. By
creating a much smaller list of only load/store operations the first time a single basic
block is encountered and reusing that list when the same block is encountered again,
this function now runs ~10X faster.
In my test case:
out/Default/cc_unittests --gtest_filter=ImageBackgroundFilter.BackgroundFilterRotated_GL
The sw::optimize function went from taking almost 16s to roughly 1.5s.
Bug b/67872293
Change-Id: I7e2e2aa8dc1bf2663988fb59b58d72d9ee986e36
Reviewed-on: https://swiftshader-review.googlesource.com/19408
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
@@ -266,6 +266,22 @@ namespace | ||
266 | 266 | { |
267 | 267 | Ice::CfgNode *entryBlock = function->getEntryNode(); |
268 | 268 | |
269 | + struct LoadStoreInst | |
270 | + { | |
271 | + LoadStoreInst(Ice::Inst* inst, bool isStore) | |
272 | + : inst(inst), | |
273 | + address(isStore ? storeAddress(inst) : loadAddress(inst)), | |
274 | + isStore(isStore) | |
275 | + { | |
276 | + } | |
277 | + | |
278 | + Ice::Inst* inst; | |
279 | + Ice::Operand *address; | |
280 | + bool isStore; | |
281 | + }; | |
282 | + | |
283 | + std::unordered_map<Ice::CfgNode*, std::vector<LoadStoreInst> > loadStoreMap; | |
284 | + | |
269 | 285 | for(Ice::Inst &alloca : entryBlock->getInsts()) |
270 | 286 | { |
271 | 287 | if(alloca.isDeleted()) |
@@ -301,56 +317,65 @@ namespace | ||
301 | 317 | |
302 | 318 | if(singleBasicBlock) |
303 | 319 | { |
304 | - auto &insts = singleBasicBlock->getInsts(); | |
320 | + if(loadStoreMap.find(singleBasicBlock) == loadStoreMap.end()) | |
321 | + { | |
322 | + std::vector<LoadStoreInst> &loadStoreVector = loadStoreMap[singleBasicBlock]; | |
323 | + for(Ice::Inst &inst : singleBasicBlock->getInsts()) | |
324 | + { | |
325 | + if(inst.isDeleted()) | |
326 | + { | |
327 | + continue; | |
328 | + } | |
329 | + | |
330 | + bool isStoreInst = isStore(inst); | |
331 | + bool isLoadInst = isLoad(inst); | |
332 | + | |
333 | + if(isStoreInst || isLoadInst) | |
334 | + { | |
335 | + loadStoreVector.push_back(LoadStoreInst(&inst, isStoreInst)); | |
336 | + } | |
337 | + } | |
338 | + } | |
339 | + | |
305 | 340 | Ice::Inst *store = nullptr; |
306 | 341 | Ice::Operand *storeValue = nullptr; |
307 | 342 | bool unmatchedLoads = false; |
308 | 343 | |
309 | - for(Ice::Inst &inst : insts) | |
344 | + for (auto& loadStoreInst : loadStoreMap[singleBasicBlock]) | |
310 | 345 | { |
311 | - if(inst.isDeleted()) | |
346 | + Ice::Inst* inst = loadStoreInst.inst; | |
347 | + | |
348 | + if((loadStoreInst.address != address) || inst->isDeleted()) | |
312 | 349 | { |
313 | 350 | continue; |
314 | 351 | } |
315 | 352 | |
316 | - if(isStore(inst)) | |
353 | + if(loadStoreInst.isStore) | |
317 | 354 | { |
318 | - if(storeAddress(&inst) != address) | |
319 | - { | |
320 | - continue; | |
321 | - } | |
322 | - | |
323 | 355 | // New store found. If we had a previous one, try to eliminate it. |
324 | 356 | if(store && !unmatchedLoads) |
325 | 357 | { |
326 | 358 | // If the previous store is wider than the new one, we can't eliminate it |
327 | 359 | // because there could be a wide load reading its non-overwritten data. |
328 | - if(storeSize(&inst) >= storeSize(store)) | |
360 | + if(storeSize(inst) >= storeSize(store)) | |
329 | 361 | { |
330 | 362 | deleteInstruction(store); |
331 | 363 | } |
332 | 364 | } |
333 | 365 | |
334 | - store = &inst; | |
366 | + store = inst; | |
335 | 367 | storeValue = storeData(store); |
336 | 368 | unmatchedLoads = false; |
337 | 369 | } |
338 | - else if(isLoad(inst)) | |
370 | + else | |
339 | 371 | { |
340 | - Ice::Inst *load = &inst; | |
341 | - | |
342 | - if(loadAddress(load) != address) | |
343 | - { | |
344 | - continue; | |
345 | - } | |
346 | - | |
347 | - if(!loadTypeMatchesStore(load, store)) | |
372 | + if(!loadTypeMatchesStore(inst, store)) | |
348 | 373 | { |
349 | 374 | unmatchedLoads = true; |
350 | 375 | continue; |
351 | 376 | } |
352 | 377 | |
353 | - replace(load, storeValue); | |
378 | + replace(inst, storeValue); | |
354 | 379 | } |
355 | 380 | } |
356 | 381 | } |