Commit Graph

243 Commits

Author SHA1 Message Date
Sebastian Pop b08a52898a execute cloog specific testcases only with CLOOG_FOUND
llvm-svn: 169159
2012-12-03 21:33:40 +00:00
Patrik Hägglund b476cdfde5 Fix tests with broken datalayout strings.
Buildbot failure at r168785.

llvm-svn: 168791
2012-11-28 13:30:31 +00:00
Sebastian Pop ee4baf3eec do not execute the OpenMP tests when cloog is not found
llvm-svn: 168724
2012-11-27 21:15:15 +00:00
Tobias Grosser 3344f733fd test: LLVM supports now vectors of arbitrary pointers
This allows Polly to vectorize more code. Fix the relevant test cases.

llvm-svn: 167923
2012-11-14 08:25:52 +00:00
Tobias Grosser 38ea9cd721 Tests: Pipe test files into 'opt'
Use 'opt < %s' instead of just 'opt %s' to ensure that no temporary files are
created.

llvm-svn: 167372
2012-11-04 16:56:20 +00:00
Tobias Grosser dcebf1e9da Tests: remove ModuleID lines
llvm-svn: 167284
2012-11-02 06:09:20 +00:00
Tobias Grosser 41b20a62c9 Tests: move content of .c files in .ll
llvm-svn: 167283
2012-11-02 06:08:39 +00:00
Tobias Grosser 3eb851f370 Remove runtime tests from polly test suite
Similar to LLVM we now follow the policy of only having LLVM-IR level tests in
the Polly test suite. Testing for miscompilation of larger programs should be
done with the llvm test suite.

llvm-svn: 167255
2012-11-01 21:44:59 +00:00
Tobias Grosser 81a1c75035 Dependences: Add support to calculate memory based dependences
Instead of calculating exact value (flow) dependences, it is also possible to
calculate memory based dependences. Sometimes memory based dependences are a lot
easier to calculate. To evaluate the benefits, we add an option to calculate
memory based dependences (use -polly-value-dependences=false).

llvm-svn: 167251
2012-11-01 21:28:32 +00:00
Tobias Grosser ebe8c8cea2 Codegen: Selectively copy in array addresses for OpenMP code
The detection of values that need to be copied in to the generated OpenMP
subfunction also detects the array base addresses needed in the SCoP. Hence, it
is not necessary to unconditionally copy all the base addresses to the generated
function.

Test cases are modified to reflect this change. Arrays which are global
variables do not occur in the struct passed to the subfunction anymore. A test
case for base address copy-in is added in copy_in_array.{c,ll}.

Committed with slight modifications

Contributed by:  Armin Groesslinger <armin.groesslinger@uni-passau.de>

llvm-svn: 167215
2012-11-01 05:34:55 +00:00
Tobias Grosser 177982c478 CodeGen: Add scop-parameters to the OpenMP context
In addition to the arrays and clast variables a SCoP statement may also refer to
values defined before the SCoP or to function arguments. Detect these values and
add them to the set of values passed to the function generated for OpenMP
parallel execution of a clast.

Committed with additional test cases and some refactoring.

Contributed by:  Armin Groesslinger  <armin.groesslinger@uni-passau.de>

llvm-svn: 167214
2012-11-01 05:34:48 +00:00
Tobias Grosser a17f666f99 Codegen: Copy and restore the ValueMap and ClastVars explicitly
When generating OpenMP or GPGPU code the original ValueMap and ClastVars must be
kept. We already recovered the original ClastVars by reverting the changes, but
we did not keep the content of the ValueMap. This patch keeps now an explicit
copy of both maps and restores them after generating OpenMP or GPGPU code.

This is an adapted version of a patch contributed by:
Armin Groesslinger  <armin.groesslinger@uni-passau.de>

llvm-svn: 167213
2012-11-01 05:34:35 +00:00
Tobias Grosser 6c8e696618 cmake: Use suffix for shared modules instead of the one for shared libraries
On Linux there is no difference between shared modules and shared libaries, both
are '.so' files. However, on darwin only shared modules are '.so' files. Shared
libraries have the '.dynlib' suffix.

Fix test cases on darwin by expecting a shared module suffix for Polly instead
of a shared library suffix.

This fixes PR14135

Reported by:  Jack Howarth  <howarth@bromo.med.uc.edu>

llvm-svn: 166402
2012-10-21 21:08:29 +00:00
Tobias Grosser 28781423b2 isl scheduler: Do not fail when returning an empty band list
The bug was within isl. To fix it, we simply update the isl version that
is used by Polly. We still have some changes within Polly to be able to
write a proper test case.

Reported-by: Sameer Sahasrabuddhe <Sameer.Sahasrabuddhe@amd.com>
llvm-svn: 166021
2012-10-16 07:29:19 +00:00
Tobias Grosser c967d8e6e9 isl-codegen: Support '<' and '>'
Previously isl always generated '<=' or '>='. However, in many cases '<' or '>'
leads to simpler code. This commit updates isl and adds the relevant code
generation support to Polly.

llvm-svn: 166020
2012-10-16 07:29:13 +00:00
Tobias Grosser 6a2da6b9c8 Add test cases for multi-dimensional variable lengths arrays
At the moment we can handle such arrays only by conservatively assuming that
each access to such an array may touch any element in the array. It would be
great if we could improve Polly/LLVM at some point, such that we can
recover the multi-dimensionality of the accesses.

llvm-svn: 163619
2012-09-11 14:03:19 +00:00
Tobias Grosser ed29566c4e ScopInfo: Align parameters when using -polly-allow-nonaffine
This ensures that the isl sets/maps we operate on have the same parameter
dimensions. Operations on objects with different parameter dimensions are not
allow and trigger assertions.

llvm-svn: 163618
2012-09-11 13:50:21 +00:00
Tobias Grosser 6217e18a7d Add preliminary implementation for GPGPU code generation.
Translate the selected parallel loop body into a ptx string and run it with the
cuda driver API. We limit this preliminary implementation to target the
following special test cases:

  - Support only 2-dimensional parallel loops with or without only one innermost
    non-parallel loop.
  - Support write memory access to only one array in a SCoP.

The patch was committed with smaller changes to the build system:

There is now a flag to enable gpu code generation explictly. This was required
as we need the llvm.codegen() patch applied on the llvm sources, to compile this
feature correctly. Also, enabling gpu code generation does not require cuda.
This requirement was removed to allow 'make polly-test' runs, even without an
installed cuda runtime.

Contributed by:  Yabin Hu  <yabin.hwu@gmail.com>

llvm-svn: 161239
2012-08-03 12:50:07 +00:00
Hongbin Zheng 7aee737062 IndependentBLocks: Do not visit the same instruction twice when moving the
operand tree.

This patch fix Bug 13491, and the original "FIXME" in IndependentBlocks.cpp.

Patched by Kevin Fan<kevin.fan@gmail.com>.

llvm-svn: 161105
2012-08-01 08:46:11 +00:00
Tobias Grosser 6cc23b07e6 Revert "Add preliminary implementation for GPGPU code generation."
I did not take into account, that this patch fails to compile without the
llvm.codegen patch applied. This breaks buildbots.

I revert this until we found a solution to commit this without buildbots
complaining.

This reverts commit cb43ab80e94434e780a66be3b9a6ad466822fe33.

llvm-svn: 160165
2012-07-13 07:44:56 +00:00
Tobias Grosser b299d28181 Add preliminary implementation for GPGPU code generation.
Translate the selected parallel loop body into a ptx string and run it
with cuda driver API. We limit this preliminary implementation to
target the following special test cases:
  - Support only 2-dimensional parallel loops with or without only one
    innermost non-parallel loop.
  - Support write memory access to only one array in a SCoP.

Contributed by:  Yabin Hu <yabin.hwu@gmail.com>

llvm-svn: 160164
2012-07-13 07:21:00 +00:00
Tobias Grosser 96682025c7 Add some tests for the independent blocks pass.
llvm-svn: 158306
2012-06-11 10:25:12 +00:00
Tobias Grosser 18daacad61 ScopInfo: Add parameter bounds to context
Derive the maximal and minimal values of a parameter from the type it has. Add
this information to the scop context. This information is needed, to derive
optimal types during code generation.

llvm-svn: 157245
2012-05-22 10:47:27 +00:00
Hongbin Zheng 6417255283 Regression tests: Adapt the vectorize option change.
llvm-svn: 156255
2012-05-06 10:22:43 +00:00
Tobias Grosser e71c6ab54c SCEV based code generation
This is an incomplete implementation of the SCEV based code generation.
When finished it will remove the need for -indvars -enable-iv-rewrite.

For the moment it is still disabled. Even though it passes 'make polly-test',
there are still loose ends especially in respect of OpenMP code generation.

llvm-svn: 155717
2012-04-27 16:36:14 +00:00
Tobias Grosser 7c3061acdd Make vector tests less sensible to codegen changes
llvm-svn: 155438
2012-04-24 11:08:07 +00:00
Tobias Grosser 216ea58b21 ScheduleOpt: Fix crash with -enable-polly-vector
llvm-svn: 154808
2012-04-16 11:06:06 +00:00
Tobias Grosser 4cb5461dae CodeGen: Generate scalar code if vector instructions cannot be generated
This fixes two crashes that appeared in case of:
  - A load of a non vectorizable type (e.g. float**)
  - An instruction that is not vectorizable (e.g. call)

llvm-svn: 154586
2012-04-12 10:46:55 +00:00
Hongbin Zheng e2107f0999 Revert "Make the "all" target depend on polly-test, so that users can run regression"
This reverts commit 97bd8d50881000c11b65b0e033996ec5f57bcd15.

llvm-svn: 154487
2012-04-11 07:43:24 +00:00
Tobias Grosser 84ecc47e1c CodeGen: Allow Polly to do 'grouped unrolling', but no vector generation.
Grouped unrolling means that we unroll a loop such that the different instances
of a certain statement are scheduled right after each other, but we do
not generate any vector code. The idea here is that we can schedule the
bb vectorizer right afterwards and use it heuristics to decide when
vectorization should be performed.

llvm-svn: 154251
2012-04-07 06:16:08 +00:00
Tobias Grosser 0905a23806 CodeGen: Recreate old ivs with the original type
To avoid overflows we still use a larger type (i64) while calculating the value
of the old ivs.  However, we truncate the result to the type of the old iv when
providing it to the new code.

A corresponding test case is added to the polly test suite. Also, a failing test
case is fixed.

This fixes PR12311.

Contributed by: Tsingray Liu  <tsingrayliu@gmail.com>

llvm-svn: 153952
2012-04-03 12:24:32 +00:00
Tobias Grosser de49ef76f6 Remove unneeded alias analysis
llvm-svn: 153839
2012-04-01 16:49:48 +00:00
Tobias Grosser 89339067b0 CodeGen: Allow function parameters to be rewritten in getNewValue()
When deriving new values for the statements of a SCoP, we assumed that parameter
values are constant within the SCoP and consquently do not need to be rewritten.
For OpenMP code generation this assumption is wrong, as such values are not
available in the OpenMP subfunction and consequently also may need to be
rewritten.

Committed with some changes.

Contributed-By: Johannes Doerfert  <s9jodoer@stud.uni-saarland.de>
llvm-svn: 153838
2012-04-01 16:49:45 +00:00
Hongbin Zheng b5bf8cfa17 Make the "all" target depend on polly-test, so that users can run regression
tests by simply typing "make -C tools/polly/test", like llvm's regression
  tests.

llvm-svn: 153739
2012-03-30 09:27:16 +00:00
Hongbin Zheng 2700adebfa Autoconf build: Try to update LLVMPolly.so before running regression tests
llvm-svn: 153738
2012-03-30 09:27:07 +00:00
Tobias Grosser 900893d2d8 CodeGeneration: Proberly build the dominator tree
llvm-svn: 153645
2012-03-29 13:10:26 +00:00
Hongbin Zheng e53bdfe633 Use python script to silence the expected testcase fails on 32bit platform.
llvm-svn: 153644
2012-03-29 13:10:10 +00:00
Hongbin Zheng 689e84fcec Regession testing: Substitut POLLY_LIB_DIR, which is introduced by commit
r152924, by $(LibDir). Because we assume polly built by autoconf is always
  in llvm tree.

llvm-svn: 153642
2012-03-29 12:36:52 +00:00
Hongbin Zheng 0578aaf77c Don't fail the lli testcases on 32bit platform.
llvm-svn: 153440
2012-03-26 15:16:48 +00:00
Tobias Grosser cf88d84d79 test: Remove memaccess prefix
The prefix is not needed, as all test cases are already in a separate folder.

llvm-svn: 153320
2012-03-23 08:24:04 +00:00
Tobias Grosser d6adda3071 CodeGen: Full support for isl_pw expressions in modified access functions.
This also adds support for modifiable write accesses (until now only read
accesses where supported). We currently do not derive an exact type for the
expression, but assume that i64 is good enough. This will be improved in future
patches.

Contributed by: Yabin Hu <yabin.hwu@gmail.com>

llvm-svn: 153319
2012-03-23 08:21:22 +00:00
Tobias Grosser 3ec2abc5fb Don't allow pointer types in affine expressions
We currently do not support pointer types in affine expressions. Hence, we
disallow in the SCoP detection. Later we may decide to add support for them.

This fixes PR12277

Reported-By: Sebastian Pop  <sebpop@gmail.com>
llvm-svn: 152928
2012-03-16 16:36:47 +00:00
Hongbin Zheng c7584ff270 Off-tree build support: Set the path of Polly's library correctly.
llvm-svn: 152924
2012-03-16 14:34:20 +00:00
Hongbin Zheng 33254d1edf Revert "Minor change: Use config.polly_obj_root to locate Polly's library,"
This reverts commit 7dd9b6327b54b08ece32a4607d5ac093b518b79a.

llvm-svn: 152923
2012-03-16 13:49:55 +00:00
Hongbin Zheng 95c84eab5c Minor change: Use config.polly_obj_root to locate Polly's library,
so lit find Polly's library in off-tree build.

llvm-svn: 152920
2012-03-16 13:24:34 +00:00
Tobias Grosser 8a5070213a ScheduleOptimizer: Do not get dependences, if we do not calculate a schedule
This solves the 'isl_ctx freed, but some objects still reference it' problem
reported in PR12276.

llvm-svn: 152917
2012-03-16 11:51:41 +00:00
Tobias Grosser 371badaa47 SCEVValidator: Ensure that parameters are recorded correctly
This also fixes UMax where we did not correctly keep track of the parameters.
Fixes PR12275.

Reported-By: Sebastian Pop  <sebpop@gmail.com>
llvm-svn: 152913
2012-03-16 10:16:28 +00:00
Hongbin Zheng c0f53b1c00 Polly-test: Add a cmake option "POLLY_TEST_DISABLE_BAR". We can enable
this option in the configure step of Polly's builder to get more readable
 output from the stdio log.

llvm-svn: 152910
2012-03-16 09:04:09 +00:00
Tobias Grosser 3cbe5cfff3 Remove FinalRead
The FinalRead statement represented a virtual read that is executed after the
SCoP. It was used when we verified the correctness of a schedule by checking if
it yields the same FLOW dependences as the original code. This is only works, if
we have a final read that reads all memory at the end of the SCoP.
We now switched to just checking if a schedule does not introduce negative
dependences and also consider WAW WAR dependences. This restricts the schedules
a little bit more, but we do not have any optimizer that would calculate a more
complex schedule. Hence, for now final reads are obsolete.

llvm-svn: 152319
2012-03-08 15:21:51 +00:00
Tobias Grosser df3823750e CodeGen: Pass the scalar maps properly
llvm-svn: 151916
2012-03-02 15:20:35 +00:00
Tobias Grosser f6beec674e CodeGen: Simplify the generation of a splat
llvm-svn: 151912
2012-03-02 15:20:21 +00:00
Tobias Grosser b61e6318ac CodeGen: Name stmt bbs 'polly.stmt.' + OriginalName
llvm-svn: 150575
2012-02-15 09:58:46 +00:00
Tobias Grosser 04eadc476e tests: Replace . by %s
llvm-svn: 150377
2012-02-13 12:29:43 +00:00
Tobias Grosser 8518bbe39f CodeGen: Always name merge block
llvm-svn: 150337
2012-02-12 12:09:46 +00:00
Tobias Grosser 0dbbdd7637 Codegen: Give split and merge basic blocks better names
llvm-svn: 150335
2012-02-12 12:09:37 +00:00
Tobias Grosser a187964bac Support non-affine access functions in Polly.
In case we can not analyze an access function, we do not discard the SCoP, but
assume conservatively that all memory accesses that can be derived from our base
pointer may be accessed.

Patch provided by: Marcello Maggioni <hayarms@gmail.com>

llvm-svn: 146972
2011-12-20 10:43:14 +00:00
Tobias Grosser b6033396fd ScheduleOptimizer: Do not tile bands with just one dimension
llvm-svn: 146149
2011-12-08 13:02:58 +00:00
Tobias Grosser 595ec0d0e3 ClooG: Make sure ambigous schedules do not introduce complicated code
Cloog continued to split the domains even after the scattering. This lead to
complicated code.

llvm-svn: 146033
2011-12-07 11:03:48 +00:00
Tobias Grosser 39913e3648 test: Switch to new atomic instructions
This fixes the test with recent versions of LLVM that do not support
the old atomic instructions any more.

llvm-svn: 145402
2011-11-29 14:51:05 +00:00
Tobias Grosser 1e06003227 test: Add more dependences to cmake build
llvm-svn: 145400
2011-11-29 14:50:47 +00:00
Tobias Grosser f281702686 test: Do not hardcode '.so' as library suffix
Contributed by: Marcello Maggioni <hayarms@gmail.com>

llvm-svn: 145076
2011-11-22 19:40:38 +00:00
Tobias Grosser 4dca439cfc Register Passes: Use -polly-optimizer=(isl|pocc) to switch optimizers
This replaces the old option -polly-use-pocc. Also call the passes uniformly
-polly-opt-pocc and -polly-opt-isl.

llvm-svn: 145071
2011-11-22 19:40:19 +00:00
Tobias Grosser 8f99c167cd ScopInfo: Use names of simple parameters to name the isl parameter dimensions.
Parameters can be complex SCEV expressions, but they can also be single scalar
values. If a parameters is such a simple scalar value and the value is named,
use this name to name the isl parameter dimensions.

llvm-svn: 144641
2011-11-15 11:38:55 +00:00
Tobias Grosser f50fc50c80 Remove unused parameters from TempScop
llvm-svn: 144232
2011-11-09 22:35:15 +00:00
Tobias Grosser 6e9f25a5d5 Remove AffineSCEVIterator
We do not use it anymore. It was replaced by SCEVVisitors like the
SCEVValidator.

llvm-svn: 144229
2011-11-09 22:35:00 +00:00
Tobias Grosser fb47d66a06 Remove unused code from SCEVAffFunc constructor
llvm-svn: 144224
2011-11-09 22:34:39 +00:00
Tobias Grosser 5683df4a23 Remove more of SCEVAffineFunc
llvm-svn: 144223
2011-11-09 22:34:34 +00:00
Tobias Grosser db87142b26 TempScop: Remove more of the buildAffineFunction
llvm-svn: 144221
2011-11-09 22:34:24 +00:00
Tobias Grosser e6efa37e76 TempScopInfo: Remove unneeded construction of SCEVAffFunc
llvm-svn: 144220
2011-11-09 22:34:18 +00:00
Tobias Grosser 60b54f19e6 Detect Parameters directly on the SCEV.
Instead of using TempScop to find parameters, we detect them directly
on the SCEV. This allows us to remove the TempScop parameter detection
in a subsequent commit.

This fixes a bug reported by Marcello Maggioni <hayarms@gmail.com>

llvm-svn: 144087
2011-11-08 15:41:28 +00:00
Tobias Grosser 65fa78e975 TempScopInfo: Print the original SCEV instead of using SCEVAffFunc
This is reducing the impact of SCEVAffFunc

llvm-svn: 143574
2011-11-02 21:37:06 +00:00
Tobias Grosser 67707b7131 Enable prevectorization with -enable-polly-vector.
This removes the separate prevector options for the Pluto and isl scheduler.

llvm-svn: 142774
2011-10-23 20:59:40 +00:00
Tobias Grosser 22636bf498 Rename -enable-schedule-prevector to -polly-prevector
llvm-svn: 142771
2011-10-23 20:59:29 +00:00
Tobias Grosser 2ff8723d5d ScopDetection: Allow to limit the scop detection to a single function
-polly-detect-only=<functionname> allows to limit the scop detection to
a single function.

llvm-svn: 142750
2011-10-23 11:17:06 +00:00
Tobias Grosser 0e27e24751 ScopInfo: Use separate function to build context
llvm-svn: 141253
2011-10-06 00:03:48 +00:00
Tobias Grosser 7a5246a371 Test: Convert to new exception handling
llvm-svn: 141069
2011-10-04 07:53:21 +00:00
Tobias Grosser c92151516f CodeGen: Support for Cast Operations in vector code generation
llvm-svn: 139097
2011-09-04 11:45:52 +00:00
Tobias Grosser 7551c3000a CodeGen: Better separate scalar and vector code generation.
llvm-svn: 139095
2011-09-04 11:45:41 +00:00
Tobias Grosser 8ae9aca5cc CodeGen: Improve naming of copied basic blocks
It may happen that we generate the code of a basic block from the original
scop is code generated several times. The new naming scheme reduces confusing
that earlier appeared as the version numbers of the new basic blocks could
have been interpreted as part of the name of the original basic block.

llvm-svn: 139092
2011-09-04 11:45:22 +00:00
Tobias Grosser c532f12965 Fix crashes due to unaligned parameters
Due to the recent introduction of isl_id, parameters need now always to be
aligned. This was not yet taken care of in the code path of vectorization and
dependence analysis.

llvm-svn: 138555
2011-08-25 08:40:59 +00:00
Tobias Grosser 604c981f40 Temporarily remove reduction support and interchange pass
I am planning to eliminate the TempScopInfo pass. To simplify this I remove
some features that may later be added to the ScopInfo pass.

The interchange pass is currently strongly tested and furthermore ment to be
replaced by the general scheduling optimizer. Reductions itself can later
be added easily.

llvm-svn: 138219
2011-08-21 14:57:58 +00:00
Raghesh Aloor 129e867865 Memaccess: Code generation for constant access function change
Support for generating code for an access function change which is
a constant is added. 

llvm-svn: 137603
2011-08-15 02:33:39 +00:00
Raghesh Aloor 62b13120ee Memaccess: Codegeneration for a simple access function change
Code is generated for a simple access function change imported
from JSCOP file. An access of A[i] is changed to A[0]. The code
for A[0] is generated directly without refering to isl function calls.

llvm-svn: 136789
2011-08-03 17:02:50 +00:00
Raghesh Aloor 7a04f4f9ba Memaccess: Display Changed Access Relation
The changed access relations imported from JSCOP file is shown
as output of -analyze pass.

llvm-svn: 136774
2011-08-03 13:47:59 +00:00
Tobias Grosser bd2b2c7117 Add a vect target to the polly testsuite
Contributed by: Sebastian Pop <sebpop@gmail.com>

llvm-svn: 136685
2011-08-02 07:22:05 +00:00
Raghesh Aloor 3cb6628d7c MemAccess: Reading Change in Access Function
This patch reads the change in access functions from
imported JSCOP file. A test case is also added.

llvm-svn: 134991
2011-07-12 17:14:03 +00:00
Tobias Grosser 851b96e7f0 Adapt to LLVM type system changes
Remove constness of Types and do not name the structures generated in the OpenMP
code.

llvm-svn: 134980
2011-07-12 12:42:54 +00:00
Tobias Grosser 928b2d16a6 test: Do not pipe the .ll file into opt
The construct '< %s' complicates debugging with gdb --args as the content of
%s is interpreted as gdb input.

llvm-svn: 134432
2011-07-05 19:13:21 +00:00
Tobias Grosser 3770157502 test: Remove redundant function definition
The latest version of LLVM fails, if a function is defined twice in an LLVM
bitcode file.

llvm-svn: 134400
2011-07-04 23:18:17 +00:00
Tobias Grosser 8c4cfc327b CodeGeneration: Do not delete the old version of the Scop.
Instead of deleting the old code, keep it on the side in an if-branch. It will
either be deleted by the dead code elimination or we can use it as fallback.

llvm-svn: 131352
2011-05-14 19:01:49 +00:00
Hongbin Zheng 94c5df16e2 ScopDetection: Remember the functions generated by backend in a pointer set, so we
do not re-generate code for these functions.

llvm-svn: 130975
2011-05-06 02:38:20 +00:00
Hongbin Zheng e1bd40cfbd Partial support test polly for out of tree build.
llvm-svn: 130482
2011-04-29 07:34:54 +00:00
Tobias Grosser 758053788b Add initial version of Polly
This version is equivalent to commit ba26ebece8f5be84e9bd6315611d412af797147e
in the old git repository.

llvm-svn: 130476
2011-04-29 06:27:02 +00:00