Initail checking of structure swapper
authorChris Lattner <sabre@nondot.org>
Sat, 10 Nov 2001 07:28:25 +0000 (07:28 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 10 Nov 2001 07:28:25 +0000 (07:28 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1248 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Transforms/IPO/SimpleStructMutation.h [new file with mode: 0644]
lib/Transforms/IPO/SimpleStructMutation.cpp [new file with mode: 0644]

diff --git a/include/llvm/Transforms/IPO/SimpleStructMutation.h b/include/llvm/Transforms/IPO/SimpleStructMutation.h
new file mode 100644 (file)
index 0000000..62da418
--- /dev/null
@@ -0,0 +1,35 @@
+//===- llvm/Transforms/SwapStructContents.h - Permute Structs ----*- C++ -*--=//
+//
+// This pass does a simple transformation that swaps all of the elements of the
+// struct types in the program around.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SWAPSTRUCTCONTENTS_H
+#define LLVM_TRANSFORMS_SWAPSTRUCTCONTENTS_H
+
+#include "llvm/Pass.h"
+
+class SwapStructContents : public Pass {
+  Pass *StructMutator;
+public:
+  // doPassInitialization - Figure out what transformation to do
+  //
+  bool doPassInitialization(Module *M);
+
+  // doPerMethodWork - Virtual method overriden by subclasses to do the
+  // per-method processing of the pass.
+  //
+  virtual bool doPerMethodWork(Method *M) {
+    return StructMutator->doPerMethodWork(M);
+  }
+
+  // doPassFinalization - Forward to our worker.
+  //
+  virtual bool doPassFinalization(Module *M) {
+    return StructMutator->doPassFinalization(M);
+  }
+
+};
+
+#endif
diff --git a/lib/Transforms/IPO/SimpleStructMutation.cpp b/lib/Transforms/IPO/SimpleStructMutation.cpp
new file mode 100644 (file)
index 0000000..8ec7f4b
--- /dev/null
@@ -0,0 +1,98 @@
+//===- SwapStructContents.cpp - Swap structure elements around ---*- C++ -*--=//
+//
+// This pass does a simple transformation that swaps all of the elements of the
+// struct types in the program around.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "llvm/Transforms/SwapStructContents.h"
+#include "llvm/Transforms/MutateStructTypes.h"
+#include "llvm/Analysis/FindUsedTypes.h"
+#include "llvm/Analysis/FindUnsafePointerTypes.h"
+#include "llvm/DerivedTypes.h"
+
+// PruneTypes - Given a type Ty, make sure that neither it, or one of its
+// subtypes, occur in TypesToModify.
+//
+static void PruneTypes(const Type *Ty, set<const StructType*> &TypesToModify,
+                       set<const Type*> &ProcessedTypes) {
+  if (ProcessedTypes.count(Ty)) return;  // Already been checked
+  ProcessedTypes.insert(Ty);
+
+  // If the element is in TypesToModify, remove it now...
+  if (const StructType *ST = dyn_cast<StructType>(Ty))
+    TypesToModify.erase(ST);  // This doesn't fail if the element isn't present
+
+  // Remove all types that this type contains as well...
+  //
+  for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
+       I != E; ++I)
+    PruneTypes(*I, TypesToModify, ProcessedTypes);
+}
+
+
+
+// doPassInitialization - This does all of the work of the pass
+//
+bool SwapStructContents::doPassInitialization(Module *M) {
+  // We need to know which types to modify, and which types we CAN'T modify
+  FindUsedTypes          FUT/*(true)*/; // TODO: Do symbol tables as well
+  FindUnsafePointerTypes FUPT;
+
+  // Simutaneously find all of the types used, and all of the types that aren't
+  // safe.
+  //
+  vector<Pass*> Analyses;
+  Analyses.push_back(&FUT);
+  Analyses.push_back(&FUPT);
+  Pass::runAllPasses(M, Analyses);  // Do analyses
+
+
+  // Get the results out of the analyzers...
+  const set<PointerType*> &UnsafePTys = FUPT.getUnsafeTypes();
+  const set<const Type *> &UsedTypes  = FUT.getTypes();
+
+
+  // Combine the two sets, weeding out non structure types.  Closures should
+  // would be nice.
+  set<const StructType*> TypesToModify;
+  for (set<const Type *>::const_iterator I = UsedTypes.begin(), 
+         E = UsedTypes.end(); I != E; ++I)
+    if (const StructType *ST = dyn_cast<StructType>(*I))
+      TypesToModify.insert(ST);
+
+
+  // Go through the Unsafe types and remove all types from TypesToModify that we
+  // are not allowed to modify, because that would be unsafe.
+  //
+  set<const Type*> ProcessedTypes;
+  for (set<PointerType*>::const_iterator I = UnsafePTys.begin(),
+         E = UnsafePTys.end(); I != E; ++I)
+    PruneTypes(*I, TypesToModify, ProcessedTypes);
+
+
+  // Build up a set of structure types that we are going to modify, and
+  // information describing how to modify them.
+  map<const StructType*, vector<int> > Transforms;
+
+  for (set<const StructType*>::iterator I = TypesToModify.begin(),
+         E = TypesToModify.end(); I != E; ++I) {
+    const StructType *ST = *I;
+    unsigned NumElements = ST->getElementTypes().size();
+
+    vector<int> &Transform = Transforms[ST];  // Fill in the map directly
+    Transform.reserve(NumElements);
+
+    // The transformation to do is: just simply swap the elements
+    for (unsigned i = 0; i < NumElements; ++i)
+      Transform.push_back(NumElements-i-1);
+  }
+  
+  // Create the Worker to do our stuff for us...
+  StructMutator = new MutateStructTypes(Transforms);
+  
+  // Do initial work.
+  return StructMutator->doPassInitialization(M);
+}
+