OSDN Git Service

Eliminate unused allocas.
authorNicolas Capens <capn@google.com>
Thu, 24 Nov 2016 19:43:05 +0000 (14:43 -0500)
committerNicolas Capens <capn@google.com>
Tue, 13 Dec 2016 16:42:10 +0000 (16:42 +0000)
Bug swiftshader:27

Change-Id: If085323dc6cc4325c6ff55c1021e98db94a75302
Reviewed-on: https://swiftshader-review.googlesource.com/8228
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
src/Reactor/Optimizer.cpp [new file with mode: 0644]
src/Reactor/Optimizer.hpp [new file with mode: 0644]
src/Reactor/Subzero.vcxproj
src/Reactor/Subzero.vcxproj.filters
src/Reactor/SubzeroReactor.cpp

diff --git a/src/Reactor/Optimizer.cpp b/src/Reactor/Optimizer.cpp
new file mode 100644 (file)
index 0000000..b528993
--- /dev/null
@@ -0,0 +1,110 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "Optimizer.hpp"
+
+#include "src/IceCfg.h"
+#include "src/IceCfgNode.h"
+
+#include <map>
+#include <vector>
+
+namespace
+{
+       class Optimizer
+       {
+       public:
+               void run(Ice::Cfg *function);
+
+       private:
+               void analyzeUses(Ice::Cfg *function);
+               void eliminateUnusedAllocas();
+
+               Ice::Cfg *function;
+
+               std::map<Ice::Operand*, std::vector<Ice::Inst*>> uses;
+       };
+
+       void Optimizer::run(Ice::Cfg *function)
+       {
+               this->function = function;
+
+               analyzeUses(function);
+
+               eliminateUnusedAllocas();
+       }
+
+       void Optimizer::eliminateUnusedAllocas()
+       {
+               Ice::CfgNode *entryBlock = function->getEntryNode();
+
+               for(Ice::Inst &alloca : entryBlock->getInsts())
+               {
+                       if(!llvm::isa<Ice::InstAlloca>(alloca))
+                       {
+                               return;   // Allocas are all at the top
+                       }
+
+                       Ice::Operand *address = alloca.getDest();
+
+                       if(uses[address].empty())
+                       {
+                               alloca.setDeleted();
+                       }
+               }
+       }
+
+       void Optimizer::analyzeUses(Ice::Cfg *function)
+       {
+               uses.clear();
+
+               for(Ice::CfgNode *basicBlock : function->getNodes())
+               {
+                       for(Ice::Inst &instruction : basicBlock->getInsts())
+                       {
+                               if(instruction.isDeleted())
+                               {
+                                       continue;
+                               }
+
+                               for(int i = 0; i < instruction.getSrcSize(); i++)
+                               {
+                                       int unique = 0;
+                                       for(; unique < i; unique++)
+                                       {
+                                               if(instruction.getSrc(i) == instruction.getSrc(unique))
+                                               {
+                                                       break;
+                                               }
+                                       }
+
+                                       if(i == unique)
+                                       {
+                                               uses[instruction.getSrc(i)].push_back(&instruction);
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+namespace sw
+{
+       void optimize(Ice::Cfg *function)
+       {
+               Optimizer optimizer;
+
+               optimizer.run(function);
+       }
+}
\ No newline at end of file
diff --git a/src/Reactor/Optimizer.hpp b/src/Reactor/Optimizer.hpp
new file mode 100644 (file)
index 0000000..c050717
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_Optimizer_hpp
+#define sw_Optimizer_hpp
+
+#include "src/IceCfg.h"
+
+namespace sw
+{
+       void optimize(Ice::Cfg *function);
+}
+
+#endif   // sw_Optimizer_hpp
index 2a11524..59c1669 100644 (file)
     <ClCompile Include="$(SolutionDir)third_party\pnacl-subzero\src\IceTimerTree.cpp" />\r
     <ClCompile Include="$(SolutionDir)third_party\pnacl-subzero\src\IceTypes.cpp" />\r
     <ClCompile Include="$(SolutionDir)third_party\pnacl-subzero\src\IceVariableSplitting.cpp" />\r
+    <ClCompile Include="Optimizer.cpp" />\r
     <ClCompile Include="Routine.cpp" />\r
     <ClCompile Include="SubzeroReactor.cpp" />\r
   </ItemGroup>\r
     <ClInclude Include="$(SolutionDir)third_party\pnacl-subzero\src\IceConditionCodesX8664.h" />\r
     <ClInclude Include="$(SolutionDir)third_party\pnacl-subzero\src\IceInstX8664.h" />\r
     <ClInclude Include="$(SolutionDir)third_party\pnacl-subzero\src\IceRegistersX8664.h" />\r
+    <ClInclude Include="Optimizer.hpp" />\r
   </ItemGroup>\r
   <ItemGroup>\r
     <None Include="$(SolutionDir)third_party\pnacl-subzero\src\IceClFlags.def" />\r
index b415ca1..64c9db6 100644 (file)
     <ClCompile Include="$(SolutionDir)third_party\pnacl-subzero\src\IceTargetLoweringX8664.cpp">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="Optimizer.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="$(SolutionDir)third_party\pnacl-subzero\src\IceAssembler.h">\r
     <ClInclude Include="$(SolutionDir)third_party\pnacl-subzero\src\IceRegistersX8664.h">\r
       <Filter>Header Files</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="Optimizer.hpp">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <None Include="$(SolutionDir)third_party\pnacl-subzero\src\IceClFlags.def">\r
index da66206..aacec93 100644 (file)
@@ -17,6 +17,8 @@
 #include "Reactor.hpp"
 #include "Routine.hpp"
 
+#include "Optimizer.hpp"
+
 #include "src/IceTypes.h"
 #include "src/IceCfg.h"
 #include "src/IceELFStreamer.h"
@@ -422,6 +424,8 @@ namespace sw
                std::string asciiName(wideName.begin(), wideName.end());
                ::function->setFunctionName(Ice::GlobalString::createWithString(::context, asciiName));
 
+               optimize();
+
                ::function->translate();
                assert(!::function->hasError());
 
@@ -449,6 +453,7 @@ namespace sw
 
        void Nucleus::optimize()
        {
+               sw::optimize(::function);
        }
 
        Value *Nucleus::allocateStackVariable(Type *t, int arraySize)