[PATCH v2 23/50] helper-to-tcg: PrepareForTcgPass, remove functions with cycles

Anton Johansson via qemu development <[email protected]>
Newsgroups gmane.comp.emulators.qemu
Message-ID <[email protected]>
Functions with cycles are removed for two primary reasons:

  * As a simplifying assumption for register allocation which occurs down
    the line, and;

  * If a function contains cycles post-optimization neither unrolling or
    loop vectorization were deemed beneficial, and the function _might_ be
    better suited as a helper anyway.

Cycles are detected by iterating over Strongly Connected Components
(SCCs) which imply the existence of cycles if a SCC contains more than one
node, or it has a self-edge.

Signed-off-by: Anton Johansson <[email protected]>
---
 .../PrepareForTcgPass/PrepareForTcgPass.cpp   | 34 +++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/subprojects/helper-to-tcg/src/PrepareForTcgPass/PrepareForTcgPass.cpp b/subprojects/helper-to-tcg/src/PrepareForTcgPass/PrepareForTcgPass.cpp
index cea6573e41..41f317ed0b 100644
--- a/subprojects/helper-to-tcg/src/PrepareForTcgPass/PrepareForTcgPass.cpp
+++ b/subprojects/helper-to-tcg/src/PrepareForTcgPass/PrepareForTcgPass.cpp
@@ -17,9 +17,39 @@
 
 #include "PrepareForTcgPass.hpp"
 
+#include <llvm/ADT/SCCIterator.h>
+#include <llvm/ADT/SmallPtrSet.h>
+#include <llvm/IR/Function.h>
+#include <llvm/IR/Module.h>
+
 using namespace llvm;
 
-PreservedAnalyses PrepareForTcgPass::run(Module &M, ModuleAnalysisManager &MAM)
-{
+static void removeFunctionsWithLoops(Module &M, ModuleAnalysisManager &MAM) {
+    // Iterate over all Strongly Connected Components (SCCs), a SCC implies
+    // the existence of loops if:
+    //   - it has more than one node, or;
+    //   - it has a self-edge.
+    SmallPtrSet<Function *, 16> FunctionsToRemove;
+    for (Function &F : M) {
+        if (F.isDeclaration()) {
+            continue;
+        }
+        for (auto It = scc_begin(&F); !It.isAtEnd(); ++It) {
+            if (It.hasCycle()) {
+                FunctionsToRemove.insert(&F);
+                break;
+            }
+        }
+    }
+
+    for (Function *F : FunctionsToRemove) {
+        F->setComdat(nullptr);
+        F->deleteBody();
+    }
+}
+
+PreservedAnalyses PrepareForTcgPass::run(Module &M,
+                                         ModuleAnalysisManager &MAM) {
+    removeFunctionsWithLoops(M, MAM);
     return PreservedAnalyses::none();
 }
-- 
2.52.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.