Commit Graph

376 Commits

Author SHA1 Message Date
Bill Wendling f891bf8b30 Add the 'resume' instruction for the new EH rewrite.
This adds the 'resume' instruction class, IR parsing, and bitcode reading and
writing. The 'resume' instruction resumes propagation of an existing (in-flight)
exception whose unwinding was interrupted with a 'landingpad' instruction (to be
added later).

llvm-svn: 136589
2011-07-31 06:30:59 +00:00
Bill Wendling ad088e6724 Revert r136253, r136263, r136269, r136313, r136325, r136326, r136329, r136338,
r136339, r136341, r136369, r136387, r136392, r136396, r136429, r136430, r136444,
r136445, r136446, r136253 pending review.

llvm-svn: 136556
2011-07-30 05:42:50 +00:00
Bill Wendling 6c923bb8d9 Merge the contents from exception-handling-rewrite to the mainline.
This adds the new instructions 'landingpad' and 'resume'.

llvm-svn: 136253
2011-07-27 20:18:04 +00:00
Jay Foad d1b7849d49 Convert GetElementPtrInst to use ArrayRef.
llvm-svn: 135904
2011-07-25 09:48:08 +00:00
Jay Foad 17bab44308 Fix more MSVC warnings caused by a cases I missed when converting
ConstantExpr::getGetElementPtr to use ArrayRef.

llvm-svn: 135762
2011-07-22 08:52:50 +00:00
Jay Foad 2f5fc8c67d Make better use of ConstantExpr::getGetElementPtr's InBounds parameter.
llvm-svn: 135676
2011-07-21 15:15:37 +00:00
Jay Foad ed8db7d9df Convert ConstantExpr::getGetElementPtr and
ConstantExpr::getInBoundsGetElementPtr to use ArrayRef.

llvm-svn: 135673
2011-07-21 14:31:17 +00:00
Chris Lattner 5cf753c95e move tier out of an anonymous namespace, it doesn't make sense
to for it to be an an anon namespace and be in a header.

Eliminate some extraenous uses of tie.

llvm-svn: 135669
2011-07-21 06:21:31 +00:00
Jay Foad f4b14a2b0d Use ArrayRef in ConstantFoldInstOperands and ConstantFoldCall.
llvm-svn: 135477
2011-07-19 13:32:40 +00:00
Chris Lattner 229907cd11 land David Blaikie's patch to de-constify Type, with a few tweaks.
llvm-svn: 135375
2011-07-18 04:54:35 +00:00
Chris Lattner cc19efaa97 Revamp the "ConstantStruct::get" methods. Previously, these were scattered
all over the place in different styles and variants.  Standardize on two
preferred entrypoints: one that takes a StructType and ArrayRef, and one that
takes StructType and varargs.

In cases where there isn't a struct type convenient, we now add a
ConstantStruct::getAnon method (whose name will make more sense after a few
more patches land).  

It would be "really really nice" if the ConstantStruct::get and 
ConstantVector::get methods didn't make temporary std::vectors.

llvm-svn: 133412
2011-06-20 04:01:31 +00:00
Nick Lewycky c66d455e50 Don't crash owhen ComputeLoadResult can't compute the result of the load.
llvm-svn: 132290
2011-05-29 19:33:36 +00:00
Nick Lewycky a3bb03e400 Obey the isVolatile bit on memory intrinsics when analyzing uses of a global
variable. Noticed by inspection.

Simulate memset in EvaluateFunction where the target of the memset and the
value we're setting are both the null value. Fixes PR10047!

llvm-svn: 132288
2011-05-29 18:41:56 +00:00
Chris Lattner 1a1acc2191 fix PR9856, an incorrectly conservative assertion: a global can be
"stored once" even if its address is compared.

llvm-svn: 131849
2011-05-22 07:15:13 +00:00
Nick Lewycky 0f85789800 Just because a GlobalVariable's initializer is [N x { i32, void ()* }] doesn't
mean that it has to be ConstantArray of ConstantStruct. We might have
ConstantAggregateZero, at either level, so don't crash on that.

Also, semi-deprecate the sentinal value. The linker isn't aware of sentinals so
we end up with the two lists appended, each with their "sentinals" on them.
Different parts of LLVM treated sentinals differently, so make them all just
ignore the single entry and continue on with the rest of the list.

llvm-svn: 129307
2011-04-11 22:11:20 +00:00
Jay Foad 7c14a558fe Don't include Operator.h from InstrTypes.h.
llvm-svn: 129271
2011-04-11 09:35:34 +00:00
Eli Friedman 9cca0715aa Add back a couple checks removed by r129128; the fact that an intitializer
is an array of structures doesn't imply it's a ConstantArray of
ConstantStruct.

llvm-svn: 129207
2011-04-09 09:11:09 +00:00
Nick Lewycky 466d0c1f93 llvm.global_[cd]tor is defined to be either external, or appending with an array
of { i32, void ()* }. Teach the verifier to verify that, deleting copies of
checks strewn about.

llvm-svn: 129128
2011-04-08 07:30:21 +00:00
Jay Foad 52131344a2 Remove PHINode::reserveOperandSpace(). Instead, add a parameter to
PHINode::Create() giving the (known or expected) number of operands.

llvm-svn: 128537
2011-03-30 11:28:46 +00:00
Jay Foad e0938d8a87 (Almost) always call reserveOperandSpace() on newly created PHINodes.
llvm-svn: 128535
2011-03-30 11:19:20 +00:00
Anders Carlsson 1cc8073bb3 Handle another case that Frits suggested.
llvm-svn: 128068
2011-03-22 03:21:01 +00:00
Anders Carlsson 4dd420f193 More cleanups to the OptimizeEmptyGlobalCXXDtors GlobalOpt function.
llvm-svn: 127997
2011-03-21 14:54:40 +00:00
Anders Carlsson 701822a48e As suggested by Nick Lewycky, ignore debugging intrinsics when trying to decide whether a destructor is empty or not.
llvm-svn: 127985
2011-03-21 02:42:27 +00:00
Nick Lewycky d078183725 Fix comments
llvm-svn: 127984
2011-03-21 02:26:01 +00:00
Anders Carlsson 336fd90f4d Don't try to eliminate invokes to __cxa_atexit.
llvm-svn: 127976
2011-03-20 20:21:33 +00:00
Anders Carlsson fcec2f519a Don't segfault on mutual recursion, as pointed out by Frits.
llvm-svn: 127975
2011-03-20 20:16:43 +00:00
Anders Carlsson 48a44911d3 Address comments from Frits van Bommel.
llvm-svn: 127974
2011-03-20 19:51:13 +00:00
Anders Carlsson ee6bc70d2f Add an optimization to GlobalOpt that eliminates calls to __cxa_atexit, if the function passed is empty.
llvm-svn: 127970
2011-03-20 17:59:11 +00:00
Chris Lattner 69229316aa convert ConstantVector::get to use ArrayRef.
llvm-svn: 125537
2011-02-15 00:14:00 +00:00
Chris Lattner 34442e6ebf revert my ConstantVector patch, it seems to have made the llvm-gcc
builders unhappy.

llvm-svn: 125504
2011-02-14 18:15:46 +00:00
Chris Lattner d9f5b88548 Switch ConstantVector::get to use ArrayRef instead of a pointer+size
idiom.  Change various clients to simplify their code.

llvm-svn: 125487
2011-02-14 07:55:32 +00:00
Rafael Espindola fc355bc070 Add unnamed_addr when we can show that address of a global is not used.
llvm-svn: 123834
2011-01-19 16:32:21 +00:00
Rafael Espindola ecd5b9abe9 Reduce indentation and remove commented out code.
llvm-svn: 123729
2011-01-18 04:36:06 +00:00
Owen Anderson 4e54efd625 Improve the safety of my globalopt enhancement by ensuring that the bitcast
of the stored value to the new store type is always.  Also, add a testcase.

llvm-svn: 123563
2011-01-16 04:33:33 +00:00
Chris Lattner 8b4952fcf7 simplify this code, it is still broken but will follow up on llvm-commits.
llvm-svn: 123558
2011-01-16 02:05:10 +00:00
Benjamin Kramer ed5f2e504e Try to unbreak selfhost.
llvm-svn: 123537
2011-01-15 11:25:34 +00:00
Owen Anderson 3e2f6cf7ae Fix a false-positive warning.
llvm-svn: 123480
2011-01-14 22:31:13 +00:00
Owen Anderson 9eb7cb48e4 Enhance GlobalOpt to be able evaluate initializers that involve stores through
bitcasts, at least in simple cases.  This fixes clang's CodeGenCXX/virtual-base-dtor.cpp

llvm-svn: 123477
2011-01-14 22:19:20 +00:00
Chris Lattner 1903c42b97 fix a globalopt crash on two Adobe-C++ testcases that the recent
loop idiom pass exposed.

llvm-svn: 122674
2011-01-01 22:31:46 +00:00
Chris Lattner 0d71c4f564 reapply r121100 with a tweak to constant fold ConstExprs with TargetData
(if available) as we go so that we get simple constantexprs not insane ones.
This fixes the failure of clang/test/CodeGenCXX/virtual-base-ctor.cpp
that the previous iteration of this patch had.

llvm-svn: 121111
2010-12-07 04:33:29 +00:00
Eric Christopher f10dcfb9fb Temporarily revert r121100 as it's causing clang to fail
CodeGenCXX/virtual-base-ctor.cpp.

llvm-svn: 121102
2010-12-07 02:41:11 +00:00
Chris Lattner 287f4366c1 fix PR8710 - teach global opt that some constantexprs are too complex to
put in a global variable's initializer.

llvm-svn: 121100
2010-12-07 01:59:32 +00:00
Chris Lattner 7ff0ba41bd replace a linear scan with a symtab lookup, reduce indentation.
No functionality change.

llvm-svn: 121042
2010-12-06 21:53:07 +00:00
Owen Anderson 6c18d1aac0 Get rid of static constructors for pass registration. Instead, every pass exposes an initializeMyPassFunction(), which
must be called in the pass's constructor.  This function uses static dependency declarations to recursively initialize
the pass's dependencies.

Clients that only create passes through the createFooPass() APIs will require no changes.  Clients that want to use the
CommandLine options for passes will need to manually call the appropriate initialization functions in PassInitialization.h
before parsing commandline arguments.

I have tested this with all standard configurations of clang and llvm-gcc on Darwin.  It is possible that there are problems
with the static dependencies that will only be visible with non-standard options.  If you encounter any crash in pass
registration/creation, please send the testcase to me directly.

llvm-svn: 116820
2010-10-19 17:21:58 +00:00
Mikhail Glushenkov 2072db24ed GlobalOpt: EvaluateFunction() must not evaluate stores to weak_odr globals.
Fixes PR8389.

llvm-svn: 116812
2010-10-19 16:47:23 +00:00
Mikhail Glushenkov cf2afe008d Trailing whitespace.
llvm-svn: 116749
2010-10-18 21:16:00 +00:00
Owen Anderson df7a4f2515 Now with fewer extraneous semicolons!
llvm-svn: 115996
2010-10-07 22:25:06 +00:00
Owen Anderson a7aed18624 Reapply r110396, with fixes to appease the Linux buildbot gods.
llvm-svn: 110460
2010-08-06 18:33:48 +00:00
Owen Anderson bda59bd247 Revert r110396 to fix buildbots.
llvm-svn: 110410
2010-08-06 00:23:35 +00:00
Owen Anderson 755aceb5d0 Don't use PassInfo* as a type identifier for passes. Instead, use the address of the static
ID member as the sole unique type identifier.  Clean up APIs related to this change.

llvm-svn: 110396
2010-08-05 23:42:04 +00:00
Oscar Fuentes 40b31ad3ee Prefix `next' iterator operation with `llvm::'.
Fixes potential ambiguity problems on VS 2010.

Patch by nobled!

llvm-svn: 110029
2010-08-02 06:00:15 +00:00
Gabor Greif 3e44ea1917 undo 80 column trespassing I caused
llvm-svn: 109092
2010-07-22 10:37:47 +00:00
Owen Anderson a57b97e7e7 Fix batch of converting RegisterPass<> to INTIALIZE_PASS().
llvm-svn: 109045
2010-07-21 22:09:45 +00:00
Chris Lattner 27e997a168 eliminate unlockedRefineAbstractTypeTo, types are all per-llvmcontext,
so there is no locking involved in type refinement.

llvm-svn: 108553
2010-07-16 20:50:13 +00:00
Gabor Greif a75ed761a9 cache result of operator*
llvm-svn: 108144
2010-07-12 14:13:15 +00:00
Chris Lattner 601e390a3b make the prototypes for CreateMalloc and CreateFree more consistent. Patch
by Hans Vandierendonck from PR7605

llvm-svn: 108116
2010-07-12 00:57:28 +00:00
Gabor Greif 9d5ae03404 cache result of operator*
llvm-svn: 107990
2010-07-09 16:51:20 +00:00
Gabor Greif 218f5541b2 use ArgOperand API and CallSite for arg range; add necessary casts and perform some cosmetics
llvm-svn: 106747
2010-06-24 14:42:01 +00:00
Gabor Greif 27b3d55194 use abstract accessors to CallInst
llvm-svn: 101899
2010-04-20 13:13:04 +00:00
Eric Christopher 7258dcd77f Revert 101465, it broke internal OpenGL testing.
Probably the best way to know that all getOperand() calls have been handled
is to replace that API instead of updating.

llvm-svn: 101579
2010-04-16 23:37:20 +00:00
Gabor Greif f375520f7b reapply r101434
with a fix for self-hosting

rotate CallInst operands, i.e. move callee to the back
of the operand array

the motivation for this patch are laid out in my mail to llvm-commits:
more efficient access to operands and callee, faster callgraph-construction,
smaller compiler binary

llvm-svn: 101465
2010-04-16 15:33:14 +00:00
Gabor Greif 403e9694f9 back out r101423 and r101397, they break llvm-gcc self-host on darwin10
llvm-svn: 101434
2010-04-16 01:16:20 +00:00
Gabor Greif 33ae80bff7 reapply r101364, which has been backed out in r101368
with a fix

rotate CallInst operands, i.e. move callee to the back
of the operand array

the motivation for this patch are laid out in my mail to llvm-commits:
more efficient access to operands and callee, faster callgraph-construction,
smaller compiler binary

llvm-svn: 101397
2010-04-15 20:51:13 +00:00
Gabor Greif 9fd00c7d25 back out r101364, as it trips the linux nightlybot on some clang C++ tests
llvm-svn: 101368
2010-04-15 12:46:56 +00:00
Gabor Greif aafd209632 rotate CallInst operands, i.e. move callee to the back
of the operand array

the motivation for this patch are laid out in my mail to llvm-commits:
more efficient access to operands and callee, faster callgraph-construction,
smaller compiler binary

llvm-svn: 101364
2010-04-15 10:49:53 +00:00
Evan Cheng 21b588b678 - Code clean up to reduce indentation.
- TryToOptimizeStoreOfMallocToGlobal should check if TargetData is available and bail out if it is not. The transformations being done requires TD.

llvm-svn: 101285
2010-04-14 20:52:55 +00:00
Chris Lattner b9801ffcb5 fix PR6760, a missing check in heap SRoA.
llvm-svn: 100936
2010-04-10 18:19:22 +00:00
Gabor Greif 08d85da6cc fix 80-col violations
llvm-svn: 100677
2010-04-07 18:59:26 +00:00
Gabor Greif 679728790b make more two predicates constant
llvm-svn: 100549
2010-04-06 19:24:18 +00:00
Gabor Greif 08355d6cda performance: get rid of repeated dereferencing of use_iterator by caching its result
llvm-svn: 100547
2010-04-06 19:14:05 +00:00
Gabor Greif a21bc0fbd5 const-ize predicate ValueIsOnlyUsedLocallyOrStoredToOneGlobal
llvm-svn: 100546
2010-04-06 18:58:22 +00:00
Gabor Greif 0439789023 use CallSite to access calls vs. invokes uniformly
and remove assumptions about operand order

llvm-svn: 100544
2010-04-06 18:45:08 +00:00
Dan Gohman 4bd755419f Revert the recent alignment changes. They're broken for -Os because,
in particular, they end up aligning strings at 16-byte boundaries, and
there's no way for GlobalOpt to check OptForSize.

llvm-svn: 100172
2010-04-02 03:04:37 +00:00
Dan Gohman c671347fcb Make globalopt refine global variable alignment.
llvm-svn: 100160
2010-04-02 00:14:16 +00:00
Gabor Greif 5d5db5342b Introduce ImmutableCallSite, useful for contexts where no mutation
is necessary. Inherits from new templated baseclass CallSiteBase<>
which is highly customizable. Base CallSite on it too, in a configuration
that allows full mutation.
Adapt some call sites in analyses to employ ImmutableCallSite.

llvm-svn: 100100
2010-04-01 08:21:08 +00:00
Gabor Greif febf6ab718 Add a setCalledFunction member to InvokeInst (like in CallInst)
and use this (as well as getCalledValue) to access the callee,
instead of {g|s}etOperand(0).

llvm-svn: 99084
2010-03-20 21:00:25 +00:00
Chris Lattner 65d3a0a5f8 Fix rdar://7694996 a miscompile of 183.equake from my patch yesterday,
confusing the old MAT variable with the new GlobalType one.  This caused
us to promote the @disp global pointer into:

@disp.body = internal global double*** undef

instead of:

@disp.body = internal global [3 x double**] undef

llvm-svn: 97285
2010-02-26 23:42:13 +00:00
Chris Lattner da5fcdace0 remove dead code, by this point all uses of CI are gone.
llvm-svn: 97283
2010-02-26 23:35:25 +00:00
Chris Lattner 0521c09d97 fix PR6435 another bug from the MallocInst elimination work.
llvm-svn: 97231
2010-02-26 18:23:13 +00:00
Chris Lattner 7939f795f5 rewrite OptimizeGlobalAddressOfMalloc to fix PR6422, some bugs
introduced when mallocinst was eliminated. 

llvm-svn: 97178
2010-02-25 22:33:52 +00:00
Nick Lewycky 614fb949b9 Modernize comment.
llvm-svn: 97121
2010-02-25 06:39:10 +00:00
Duncan Sands 19d0b47b1f There are two ways of checking for a given type, for example isa<PointerType>(T)
and T->isPointerTy().  Convert most instances of the first form to the second form.
Requested by Chris.

llvm-svn: 96344
2010-02-16 11:11:14 +00:00
Duncan Sands 9dff9bec31 Uniformize the names of type predicates: rather than having isFloatTy and
isInteger, we now have isFloatTy and isIntegerTy.  Requested by Chris!

llvm-svn: 96223
2010-02-15 16:12:20 +00:00
Jakob Stoklund Olesen e27dc727e2 Keep iterating over all uses when meeting a phi node in AllUsesOfValueWillTrapIfNull().
This bug was exposed by my inliner cost changes in r94615, and caused failures
of lencod on most architectures when building with LTO.

This patch fixes lencod and 464.h264ref on x86-64 (and likely others).

llvm-svn: 94858
2010-01-29 23:54:14 +00:00
Chris Lattner 9855a6bb7c handle ConstantVector while I'm in here.
llvm-svn: 92892
2010-01-07 01:20:20 +00:00
Chris Lattner 64ecc468bd fix a globalopt crash on 'bullet' (handling evaluation of a store
to an element of a vector in a static ctor) which occurs with an 
unrelated patch I'm testing.  Annoyingly, EvaluateStoreInto basically 
does exactly the same stuff as InsertElement constant folding, but it
now handles vectors, and you can't insertelement into a vector.  It
would be 'really nice' if GEP into a vector were not legal.

llvm-svn: 92889
2010-01-07 01:16:21 +00:00
Benjamin Kramer d2564e3afb Move remaining stuff to the isInteger predicate.
llvm-svn: 92771
2010-01-05 21:05:54 +00:00
Benjamin Kramer ccce8bae14 Avoid going through the LLVMContext for type equality where it's safe to dereference the type pointer.
llvm-svn: 92726
2010-01-05 13:12:22 +00:00
David Greene 44cb8ade45 Change errs() to dbgs().
llvm-svn: 92629
2010-01-05 01:28:05 +00:00
Duncan Sands 6a3df7b0c7 Teach GlobalOpt to delete aliases with internal linkage (after
forwarding any uses).  GlobalDCE can also do this, but is only
run at -O3.

llvm-svn: 90850
2009-12-08 10:10:20 +00:00
Dan Gohman 580b80d6d9 Make ConstantFoldConstantExpression recursively visit the entire
ConstantExpr, not just the top-level operator. This allows it to
fold many more constants.

Also, make GlobalOpt call ConstantFoldConstantExpression on
GlobalVariable initializers.

llvm-svn: 89659
2009-11-23 16:22:21 +00:00
Victor Hernandez fcc77b1c02 Update computeArraySize() to use ComputeMultiple() to determine the array size associated with a malloc; also extend PerformHeapAllocSRoA() to check if the optimized malloc's arg had its highest bit set, so that it is safe for ComputeMultiple() to look through sext instructions while determining the optimized malloc's array size
llvm-svn: 86676
2009-11-10 08:32:25 +00:00
Victor Hernandez bde558c536 - new SROA mallocs should have the mallocs running-or'ed, not the malloc's bitcast
- fix ProcessInternalGlobal() debug output

llvm-svn: 86317
2009-11-07 00:41:19 +00:00
Victor Hernandez f3db915294 Re-commit r86077 now that r86290 fixes the 179.art and 175.vpr ARM regressions.
Here is the original commit message:

This commit updates malloc optimizations to operate on malloc calls that have constant int size arguments.

Update CreateMalloc so that its callers specify the size to allocate:
MallocInst-autoupgrade users use non-TargetData-computed allocation sizes.
Optimization uses use TargetData to compute the allocation size.

Now that malloc calls can have constant sizes, update isArrayMallocHelper() to use TargetData to determine the size of the malloced type and the size of malloced arrays.
Extend getMallocType() to support malloc calls that have non-bitcast uses.

Update OptimizeGlobalAddressOfMalloc() to optimize malloc calls that have non-bitcast uses.  The bitcast use of a malloc call has to be treated specially here because the uses of the bitcast need to be replaced and the bitcast needs to be erased (just like the malloc call) for OptimizeGlobalAddressOfMalloc() to work correctly.

Update PerformHeapAllocSRoA() to optimize malloc calls that have non-bitcast uses.  The bitcast use of the malloc is not handled specially here because ReplaceUsesOfMallocWithGlobal replaces through the bitcast use.

Update OptimizeOnceStoredGlobal() to not care about the malloc calls' bitcast use.

Update all globalopt malloc tests to not rely on autoupgraded-MallocInsts, but instead use explicit malloc calls with correct allocation sizes.

llvm-svn: 86311
2009-11-07 00:16:28 +00:00
Chris Lattner 46b5c642b9 remove a bunch of extraneous LLVMContext arguments
from various APIs, addressing PR5325.

llvm-svn: 86231
2009-11-06 04:27:31 +00:00
Victor Hernandez b9f5899779 Revert r86077 because it caused crashes in 179.art and 175.vpr on ARM
llvm-svn: 86213
2009-11-06 01:33:24 +00:00
Victor Hernandez 492ed30a32 Update CreateMalloc so that its callers specify the size to allocate:
MallocInst-autoupgrade users use non-TargetData-computed allocation sizes.
Optimization uses use TargetData to compute the allocation size.

Now that malloc calls can have constant sizes, update isArrayMallocHelper() to use TargetData to determine the size of the malloced type and the size of malloced arrays.
Extend getMallocType() to support malloc calls that have non-bitcast uses.

Update OptimizeGlobalAddressOfMalloc() to optimize malloc calls that have non-bitcast uses.  The bitcast use of a malloc call has to be treated specially here because the uses of the bitcast need to be replaced and the bitcast needs to be erased (just like the malloc call) for OptimizeGlobalAddressOfMalloc() to work correctly.

Update PerformHeapAllocSRoA() to optimize malloc calls that have non-bitcast uses.  The bitcast use of the malloc is not handled specially here because ReplaceUsesOfMallocWithGlobal replaces through the bitcast use.

Update OptimizeOnceStoredGlobal() to not care about the malloc calls' bitcast use.

Update all globalopt malloc tests to not rely on autoupgraded-MallocInsts, but instead use explicit malloc calls with correct allocation sizes.

llvm-svn: 86077
2009-11-05 00:03:03 +00:00
Chris Lattner b5d9c8c708 cleanups, switch GlobalDCE to SmallPtrSet instead of std::set
llvm-svn: 85730
2009-11-01 19:03:42 +00:00
Chris Lattner aa99c94e2a Revert 85678/85680. The decision is to stay with the current form of
indirectbr, thus we don't need "blockaddr(@func, null)".  Eliminate it
for simplicity.

llvm-svn: 85699
2009-11-01 01:27:45 +00:00
Chris Lattner 3c89c53f35 adjust a couple xforms to work with null bb's in BlockAddress.
llvm-svn: 85680
2009-10-31 20:13:24 +00:00