Remove old testsuite
[dyninst.git] / newtestsuite / src / dyninst / test1_37.C
1 /*
2  * Copyright (c) 1996-2004 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: test1_37.C,v 1.1 2008/10/30 19:19:24 legendre Exp $
43 /*
44  * #Name: test1_37
45  * #Desc: Instrument Loops
46  * #Dep: 
47  * #Arch:
48  * #Notes:
49  */
50
51 #include "BPatch.h"
52 #include "BPatch_Vector.h"
53 #include "BPatch_addressSpace.h"
54 #include "BPatch_snippet.h"
55
56 #include "test_lib.h"
57 #include "Callbacks.h"
58 #include "dyninst_comp.h"
59
60 class test1_37_Mutator : public DyninstMutator {
61         virtual test_results_t executeTest();
62 };
63
64 extern "C" DLLEXPORT  TestMutator *test1_37_factory() 
65 {
66         return new test1_37_Mutator();
67 }
68
69 //
70 // Start Test Case #37 - (loop instrumentation)
71 //
72
73 // sort basic blocks ascending by block number
74 static void sort_blocks(BPatch_Vector<BPatch_basicBlock*> &a, int n) 
75 {
76         for (int i=0; i<n-1; i++) 
77         {
78                 for (int j=0; j<n-1-i; j++)
79                         if (a[j+1]->getBlockNumber() < a[j]->getBlockNumber()) 
80                         {
81                                 BPatch_basicBlock* tmp = a[j]; 
82                                 a[j] = a[j+1];
83                                 a[j+1] = tmp;
84                         }
85         }
86 }
87
88 /* This method instruments the entry and exit edges of a loop with 
89    the passed-in function. It accomplishes this by looking up the entry
90    and exit blocks of the loop, finding the edges that do not come from
91    or target other blocks in the loop (respectively), and instrumenting
92    those edges. So effectively, this is a test of both our loop detection
93    and edge instrumentation facilities. Two for one, yay!
94  */
95
96 static void instrumentLoops(BPatch_addressSpace *appAddrSpace, BPatch_image *appImage,
97                 BPatch_Vector<BPatch_basicBlockLoop*> &loops,
98                 BPatch_funcCallExpr &callInc) 
99 {            
100         // for each loop (set of basic blocks)
101         for (unsigned int i = 0; i < loops.size(); i++) 
102         {
103                 BPatch_flowGraph *cfg; 
104                 BPatch_Vector<BPatch_point*> * exits;
105                 BPatch_Vector<BPatch_point*> * entries;
106
107                 cfg = loops[i]->getFlowGraph();
108
109                 // Find loop entry and exit points
110                 entries = cfg->findLoopInstPoints(BPatch_locLoopEntry,
111                                 loops[i]);
112                 exits = cfg->findLoopInstPoints(BPatch_locLoopExit,
113                                 loops[i]);
114                 // instrument those points      
115
116                 if (entries->size() == 0) 
117                 {
118                         logerror("**Failed** test #37 (instrument loops)\n");
119                         logerror("   Unable to find loop entry inst point.\n");
120                 }
121
122                 if (exits->size() == 0) 
123                 {
124                         logerror("**Failed** test #37 (instrument loops)\n");
125                         logerror("   Unable to find loop exit inst point.\n");
126                 }
127
128                 unsigned int j;
129                 BPatch_point *p = NULL;
130
131                 for (j=0;j<entries->size();j++) 
132                 {
133                         p = (*entries)[j];
134
135                         BPatchSnippetHandle * han =
136                                 appAddrSpace->insertSnippet(callInc, *p, BPatch_callBefore);
137
138                         // did we insert the snippet?
139                         if (han == NULL) 
140                         {
141                                 logerror("**Failed** test #37 (instrument loops)\n");
142                                 logerror("   Unable to insert snippet at loop entry.\n");
143                         }
144                 }
145                 for (j=0;j<exits->size();j++) 
146                 {
147                         p = (*exits)[j];
148
149                         BPatchSnippetHandle * han =
150                                 appAddrSpace->insertSnippet(callInc, *p, BPatch_callBefore);
151
152                         // did we insert the snippet?
153                         if (han == NULL) 
154                         {
155                                 logerror("**Failed** test #37 (instrument loops)\n");
156                                 logerror("   Unable to insert snippet at loop exit.\n");
157                         }
158                 }
159
160                 // we are responsible for releasing the point vectors
161                 delete entries;
162                 delete exits;
163
164                 BPatch_Vector<BPatch_basicBlockLoop*> lps;
165                 loops[i]->getOuterLoops(lps);
166
167                 // recur with this loop's outer loops
168                 instrumentLoops(appAddrSpace, appImage, lps, callInc);
169         }
170 }
171
172 static int instrumentFuncLoopsWithCall(BPatch_addressSpace *appAddrSpace, 
173                 BPatch_image *appImage,
174                 char *call_func,
175                 char *inc_func)
176 {
177         // get function * for call_func
178         BPatch_Vector<BPatch_function *> funcs;
179
180         appImage->findFunction(call_func, funcs);
181         BPatch_function *func = funcs[0];
182
183         // get function * for inc_func
184         BPatch_Vector<BPatch_function *> funcs2;
185         appImage->findFunction(inc_func, funcs2);
186         BPatch_function *incVar = funcs2[0];
187
188         if (func == NULL || incVar == NULL) 
189         {
190                 logerror("**Failed** test #37 (instrument loops)\n");
191                 logerror("    Unable to get funcions.\n");
192                 return -1;
193         }
194
195         // create func expr for incVar
196         BPatch_Vector<BPatch_snippet *> nullArgs;
197         BPatch_funcCallExpr callInc(*incVar, nullArgs);
198         checkCost(callInc);
199
200         // instrument the function's loops
201         BPatch_flowGraph *cfg = func->getCFG();
202         BPatch_Vector<BPatch_basicBlockLoop*> loops;
203         cfg->getOuterLoops(loops);
204
205         instrumentLoops(appAddrSpace, appImage, loops, callInc);
206
207         return 0;
208 }
209
210 test_results_t test1_37_Mutator::executeTest() 
211 {
212         if (isMutateeFortran(appImage)) 
213         {
214                 return SKIPPED;
215         } 
216
217         if (instrumentFuncLoopsWithCall(appAddrSpace, appImage,
218                                 "test1_37_call1", "test1_37_inc1") < 0) 
219         {
220                 return FAILED;
221         }
222
223         if (instrumentFuncLoopsWithCall(appAddrSpace, appImage,
224                                 "test1_37_call2", "test1_37_inc2") < 0) 
225         {
226                 return FAILED;
227         }
228
229         if (instrumentFuncLoopsWithCall(appAddrSpace, appImage,
230                                 "test1_37_call3", "test1_37_inc3") < 0) 
231         {
232                 return FAILED;
233         }
234
235         return PASSED;
236 }
237