1 // Copyright (C) 2009 Free Software Foundation, Inc.
2 // Contributed by Jan Sjodin <jan.sjodin@amd.com>.
4 // This file is part of the Polyhedral Compilation Package Library (libpcp).
6 // Libpcp is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU Lesser General Public License as published by
8 // the Free Software Foundation; either version 2.1 of the License, or
9 // (at your option) any later version.
11 // Libpcp is distributed in the hope that it will be useful, but WITHOUT ANY
12 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with libpcp; see the file COPYING.LIB. If not, write to the
18 // Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 // MA 02110-1301, USA.
21 // As a special exception, if you link this library with other files, so me
22 // of which are compiled with GCC, to produce an executable, this library
23 // does not by itself cause the resulting executable to be covered by the
24 // GNU General Public License. This exception does not however invalidate
25 // any other reasons why the executable file might be covered by the GNU
26 // General Public License.
28 #include "pcp_error.h"
29 #include "pcp_parser.h"
30 #include "pcp_dynamic_array.h"
31 #include "pcp_tester.h"
32 #include "pcp_emitter.h"
33 #include "pcp_scalar_order.h"
34 #include "pcp_expr_canonicalizer.h"
35 #include "pcp_domain.h"
36 #include "pcp_scattering.h"
38 // Tester Option Class
40 // Set action to ACTION.
42 bool PcpTester::PcpTest::isHelp()
48 PcpTester::PcpTestHelp::setTests(PcpArray
<PcpTest
*>* tests
)
53 PcpArray
<PcpTester::PcpTest
*>*
54 PcpTester::PcpTestHelp::getTests()
60 PcpTester::PcpTestHelp::run(const char* filename
)
62 PcpError::reportErrorNewline("Usage: pcp-tester --option filename.pcp");
63 PcpError::reportErrorNewline("Possible options are:");
65 PcpArray
<PcpTester::PcpTest
*>* tests
= this->getTests();
66 for(i
= 0; i
< tests
->getSize(); i
++)
68 PcpTester::PcpTest
* test
= tests
->get(i
);
71 PcpError::reportError("--");
72 PcpError::reportError(test
->getFlagName());
73 PcpError::reportError(" - ");
74 PcpError::reportErrorNewline(test
->getDescription());
80 PcpTester::PcpTestHelp::getFlagName()
86 PcpTester::PcpTestHelp::getDescription()
88 return "Display this message";
92 PcpTester::PcpTestHelp::isHelp()
97 PcpTester::PcpTestHelp::PcpTestHelp(PcpArray
<PcpTester::PcpTest
*>* tests
)
99 this->setTests(tests
);
102 // Run the identity test for the parser and emitter, return true
103 // if the test passes
105 PcpTester::PcpTestIdentity::run(const char* filename
)
107 PcpScop
* scop
= PcpParser::parseFile(filename
);
110 PcpError::reportErrorNewline("Fatal error, aborting");
114 const char* parsedScop
= PcpEmitter::pcpScopToString(scop
);
115 const char* parsedScop2
=
116 PcpEmitter::pcpScopToString(PcpParser::parse(parsedScop
));
117 const char* parsedScop3
=
118 PcpEmitter::pcpScopToString(PcpParser::parse(parsedScop2
));
119 bool compareSuccess
= compareScopStrings(parsedScop2
, parsedScop3
);
122 PcpError::reportError("Identity check failed for file: ");
123 PcpError::reportErrorNewline(filename
);
125 return compareSuccess
;
129 PcpTester::PcpTestIdentity::getFlagName()
135 PcpTester::PcpTestIdentity::getDescription()
137 return "Identity test for the parser and emitter";
140 PcpTester::PcpTestIdentity::PcpTestIdentity()
145 PcpTester::PcpTestScalarOrder::run(const char* filename
)
147 PcpScop
* scop
= PcpParser::parseFile(filename
);
151 PcpError::reportErrorNewline("Fatal error, aborting");
155 PcpScalarOrder
order(scop
);
161 PcpTester::PcpTestScalarOrder::getFlagName()
163 return "scalarorder";
167 PcpTester::PcpTestScalarOrder::getDescription()
169 return "test ordering of scalars (ivs and parameters)";
172 PcpTester::PcpTestScalarOrder::PcpTestScalarOrder()
177 PcpTester::PcpTestExprCanonicalize::run(const char* filename
)
179 PcpScop
* scop
= PcpParser::parseFile(filename
);
183 PcpError::reportErrorNewline("Fatal error, aborting");
187 PcpScalarOrder
order(scop
);
188 printf("SCOP BEFORE CANONICALIZATION:\n");
189 printf("%s", PcpEmitter::pcpScopToString(scop
));
190 PcpExprCanonicalizer
canonicalizer(&order
);
191 canonicalizer
.canonicalize(scop
);
192 printf("SCOP AFTER CANONICALIZATION:\n");
193 printf("%s", PcpEmitter::pcpScopToString(scop
));
198 PcpTester::PcpTestExprCanonicalize::getFlagName()
200 return "canonicalize";
204 PcpTester::PcpTestExprCanonicalize::getDescription()
206 return "Test canonicalization of expressions";
209 PcpTester::PcpTestExprCanonicalize::PcpTestExprCanonicalize()
214 PcpTester::PcpTestBuildDomain::run(const char* filename
)
216 PcpScop
* scop
= PcpParser::parseFile(filename
);
220 PcpError::reportErrorNewline("Fatal error, aborting");
224 PcpScalarOrder
order(scop
);
225 //printf("SCOP BEFORE CANONICALIZATION:\n");
226 //printf("%s", PcpEmitter::pcpScopToString(scop));
227 PcpExprCanonicalizer
canonicalizer(&order
);
228 canonicalizer
.canonicalize(scop
);
229 printf("SCOP AFTER CANONICALIZATION:\n");
230 printf("%s", PcpEmitter::pcpScopToString(scop
));
232 printf("DomainExpressions:\n");
233 PcpDomainMap
map(scop
, &canonicalizer
);
239 PcpTester::PcpTestBuildDomain::getFlagName()
241 return "builddomain";
245 PcpTester::PcpTestBuildDomain::getDescription()
247 return "Test building of statment domains";
250 PcpTester::PcpTestBuildDomain::PcpTestBuildDomain()
255 PcpTester::PcpTestBuildScattering::run(const char* filename
)
257 PcpScop
* scop
= PcpParser::parseFile(filename
);
261 PcpError::reportErrorNewline("Fatal error, aborting");
264 printf("ScatteringExpressions:\n");
265 PcpScatteringMap
map(scop
);
270 PcpTester::PcpTestBuildScattering::getFlagName()
272 return "buildscattering";
276 PcpTester::PcpTestBuildScattering::getDescription()
278 return "Test building of scattering functions";
281 PcpTester::PcpTestBuildScattering::PcpTestBuildScattering()
287 PcpTester::reportCommandLineInfo()
289 PcpError::reportErrorNewline ("Expected syntax: pcptester <action> filename");
292 // Return true if STRING is an option string (starting with '--')
295 PcpTester::isOptionString(const char* string
)
297 // Option syntax: --option
298 int length
= strlen(string
);
299 return length
>= 3 && string
[0] == '-' && string
[1] == '-';
302 // Parse OPTIONSTRING and return the corresponding option, if parsing fails
306 PcpTester::parseOption(const char* optionString
)
308 // Option syntax: --option
310 if(!isOptionString(optionString
))
312 PcpError::reportError("Illegal option string:");
313 PcpError::reportErrorNewline(optionString
);
317 PcpArray
<PcpTester::PcpTest
*>* tests
= this->getTests();
318 for(int i
= 0; i
< tests
->getSize(); i
++)
320 PcpTester::PcpTest
* test
= tests
->get(i
);
321 if(strcmp(test
->getFlagName(), &(optionString
[2])) == 0)
325 PcpError::reportError("Unknown option:");
326 PcpError::reportErrorNewline(optionString
);
327 PcpTestHelp
testHelp(this->getTests());
332 // Parse the different options given the argument count and strings from
336 // pcptester [options] filename
338 // Where options may be one or more of the following:
343 PcpArray
<PcpTester::PcpTest
*>*
344 PcpTester::parseOptions(int argc
, char** argv
)
346 PcpDynamicArray
<PcpTester::PcpTest
*>* options
=
347 new PcpDynamicArray
<PcpTester::PcpTest
*>(1);
352 while(currentArg
< argc
- 1)
354 const char* arg
= argv
[currentArg
];
355 PcpTester::PcpTest
* option
= parseOption(arg
);
357 options
->add(option
);
368 // Get the file name from the command arguments
371 PcpTester::parseFileName(int argc
, char** argv
)
373 return argv
[argc
-1];
376 // Compare two strings, return true if they are equal,
380 PcpTester::PcpTestIdentity::compareScopStrings(const char* str1
,
384 while (str1
[i
] != '\0' && str2
[i
] != '\0'
385 && str1
[i
] == str2
[i
])
389 if (str1
[i
] == '\0' && str2
[i
] == '\0')
395 PcpTester::setTests(PcpArray
<PcpTester::PcpTest
*>* tests
)
400 PcpArray
<PcpTester::PcpTest
*>*
401 PcpTester::getTests()
406 // Start the tester with given FILENAME and OPTIONS
408 PcpTester::start(const char* filename
, PcpArray
<PcpTester::PcpTest
*>* options
)
411 if(filename
== NULL
|| options
== NULL
)
413 PcpError::reportErrorNewline("Bad arguments to tester, aborting");
414 this->reportCommandLineInfo();
418 if(options
->getSize() < 1)
420 PcpError::reportErrorNewline("No actions given to tester");
421 this->reportCommandLineInfo();
427 PcpIterator
<PcpTester::PcpTest
*>* iter
= options
->getIterator();
428 for (;iter
->hasNext(); iter
->next())
430 PcpTester::PcpTest
* test
= iter
->get();
438 // Start method for the tester.
441 PcpTester::run(int argc
, char** argv
)
443 PcpArray
<PcpTester::PcpTest
*>* options
;
444 const char* filename
;
448 PcpError::reportError("Too few arguments");
449 this->reportCommandLineInfo();
453 // Special case for handling "pcptester --help"
455 && this->isOptionString(argv
[1]))
457 PcpTest
* test
= this->parseOption(argv
[1]);
465 PcpError::reportErrorNewline("Error: No filename given");
466 PcpError::reportErrorNewline("Usage: pcp-tester --option filename.pcp");
471 options
= parseOptions(argc
, argv
);
476 filename
= this->parseFileName(argc
, argv
);
478 return this->start(filename
, options
);
481 PcpTester::PcpTester()
483 PcpDynamicArray
<PcpTest
*>* tests
= new PcpDynamicArray
<PcpTest
*>();
484 tests
->add(new PcpTestHelp(tests
));
485 tests
->add(new PcpTestIdentity());
486 tests
->add(new PcpTestScalarOrder());
487 tests
->add(new PcpTestExprCanonicalize());
488 tests
->add(new PcpTestBuildDomain());
489 tests
->add(new PcpTestBuildScattering());
490 this->setTests(tests
);
493 // Main function for the pcptester
495 int main(int argc
, char** argv
)
497 PcpTester
* tester
= new PcpTester();
498 bool result
= tester
->run(argc
, argv
);
500 return result
== false;