Initail checking of structure swapper
[oota-llvm.git] / lib / Transforms / IPO / SimpleStructMutation.cpp
1 //===- SwapStructContents.cpp - Swap structure elements around ---*- C++ -*--=//
2 //
3 // This pass does a simple transformation that swaps all of the elements of the
4 // struct types in the program around.
5 //
6 //===----------------------------------------------------------------------===//
7
8
9 #include "llvm/Transforms/SwapStructContents.h"
10 #include "llvm/Transforms/MutateStructTypes.h"
11 #include "llvm/Analysis/FindUsedTypes.h"
12 #include "llvm/Analysis/FindUnsafePointerTypes.h"
13 #include "llvm/DerivedTypes.h"
14
15 // PruneTypes - Given a type Ty, make sure that neither it, or one of its
16 // subtypes, occur in TypesToModify.
17 //
18 static void PruneTypes(const Type *Ty, set<const StructType*> &TypesToModify,
19                        set<const Type*> &ProcessedTypes) {
20   if (ProcessedTypes.count(Ty)) return;  // Already been checked
21   ProcessedTypes.insert(Ty);
22
23   // If the element is in TypesToModify, remove it now...
24   if (const StructType *ST = dyn_cast<StructType>(Ty))
25     TypesToModify.erase(ST);  // This doesn't fail if the element isn't present
26
27   // Remove all types that this type contains as well...
28   //
29   for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
30        I != E; ++I)
31     PruneTypes(*I, TypesToModify, ProcessedTypes);
32 }
33
34
35
36 // doPassInitialization - This does all of the work of the pass
37 //
38 bool SwapStructContents::doPassInitialization(Module *M) {
39   // We need to know which types to modify, and which types we CAN'T modify
40   FindUsedTypes          FUT/*(true)*/; // TODO: Do symbol tables as well
41   FindUnsafePointerTypes FUPT;
42
43   // Simutaneously find all of the types used, and all of the types that aren't
44   // safe.
45   //
46   vector<Pass*> Analyses;
47   Analyses.push_back(&FUT);
48   Analyses.push_back(&FUPT);
49   Pass::runAllPasses(M, Analyses);  // Do analyses
50
51
52   // Get the results out of the analyzers...
53   const set<PointerType*> &UnsafePTys = FUPT.getUnsafeTypes();
54   const set<const Type *> &UsedTypes  = FUT.getTypes();
55
56
57   // Combine the two sets, weeding out non structure types.  Closures should
58   // would be nice.
59   set<const StructType*> TypesToModify;
60   for (set<const Type *>::const_iterator I = UsedTypes.begin(), 
61          E = UsedTypes.end(); I != E; ++I)
62     if (const StructType *ST = dyn_cast<StructType>(*I))
63       TypesToModify.insert(ST);
64
65
66   // Go through the Unsafe types and remove all types from TypesToModify that we
67   // are not allowed to modify, because that would be unsafe.
68   //
69   set<const Type*> ProcessedTypes;
70   for (set<PointerType*>::const_iterator I = UnsafePTys.begin(),
71          E = UnsafePTys.end(); I != E; ++I)
72     PruneTypes(*I, TypesToModify, ProcessedTypes);
73
74
75   // Build up a set of structure types that we are going to modify, and
76   // information describing how to modify them.
77   map<const StructType*, vector<int> > Transforms;
78
79   for (set<const StructType*>::iterator I = TypesToModify.begin(),
80          E = TypesToModify.end(); I != E; ++I) {
81     const StructType *ST = *I;
82     unsigned NumElements = ST->getElementTypes().size();
83
84     vector<int> &Transform = Transforms[ST];  // Fill in the map directly
85     Transform.reserve(NumElements);
86
87     // The transformation to do is: just simply swap the elements
88     for (unsigned i = 0; i < NumElements; ++i)
89       Transform.push_back(NumElements-i-1);
90   }
91   
92   // Create the Worker to do our stuff for us...
93   StructMutator = new MutateStructTypes(Transforms);
94   
95   // Do initial work.
96   return StructMutator->doPassInitialization(M);
97 }
98