Commit Graph

111719 Commits

Author SHA1 Message Date
Duncan P. N. Exon Smith
f416d72973 IR: Add 'distinct' MDNodes to bitcode and assembly
Propagate whether `MDNode`s are 'distinct' through the other types of IR
(assembly and bitcode).  This adds the `distinct` keyword to assembly.

Currently, no one actually calls `MDNode::getDistinct()`, so these nodes
only get created for:

  - self-references, which are never uniqued, and
  - nodes whose operands are replaced that hit a uniquing collision.

The concept of distinct nodes is still not quite first-class, since
distinct-ness doesn't yet survive across `MapMetadata()`.

Part of PR22111.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225474 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 22:38:29 +00:00
Sanjay Patel
1cbba214c7 remove function names from comments; NFC
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225473 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 22:36:56 +00:00
Hal Finkel
b7c01bf403 [PowerPC] Mark all instructions as non-cheap for MachineLICM
MachineLICM uses a callback named hasLowDefLatency to determine if an
instruction def operand has a 'low' latency. If all relevant operands have a
'low' latency, the instruction is considered too cheap to hoist out of loops
even in low-register-pressure situations. On PowerPC cores, both the embedded
cores and the others, there is no reason to believe that this is a good choice:
all instructions have a cost inside a loop, and hoisting them when not limited
by register pressure is a reasonable default.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225471 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 22:11:49 +00:00
Hal Finkel
9d1500e68f [MachineLICM] A command-line option to hoist even cheap instructions
Add a command-line option to enable hoisting even cheap instructions (in
low-register-pressure situations). This is turned off by default, but has
proved useful for testing purposes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225470 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 22:10:48 +00:00
Duncan P. N. Exon Smith
089a4ba180 CodeGen: Use handy new-fangled post-increment, NFC
Drive-by cleanup; I noticed this when reviewing the patch that became
r225466.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225468 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 21:07:55 +00:00
Akira Hatanaka
40cd57eb5c [ARM] Fix a bug in constant island pass that was triggering an assertion.
The assert was being triggered when the distance between a constant pool entry
and its user exceeded the maximally allowed distance after thumb2 branch
shortening. A padding was inserted after a thumb2 branch instruction was shrunk,
which caused the user to be out of range. This is wrong as the padding should
have been inserted by the layout algorithm so that the distance between two
instructions doesn't grow later during thumb2 instruction optimization.

This commit fixes the code in ARMConstantIslands::createNewWater to call
computeBlockSize and set BasicBlock::Unalign when a branch instruction is
inserted to create new water after a basic block. A non-zero Unalign causes
the worst-case padding to be inserted when adjustBBOffsetsAfter is called to
recompute the basic block offsets.

rdar://problem/19130476


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225467 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 20:44:50 +00:00
Duncan P. N. Exon Smith
8826cb9526 CodeGen: Use range-based for loops, NFC
Patch by Ramkumar Ramachandra!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225466 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 20:44:33 +00:00
Matt Arsenault
3b1f741856 Fix fcmp + fabs instcombines when using the intrinsic
This was only handling the libcall. This is another example
of why only the intrinsic should ever be used when it exists.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225465 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 20:09:34 +00:00
Eric Christopher
aa73f89bba The Kaleidoscope tutorial should be using "mcjit" for the library,
"jit" doesn't exist anymore.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225462 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 19:07:01 +00:00
Lang Hames
1b3d915de6 [MCJIT] Remove a few redundant MCJIT tests, and drop the extraneous datalayout
strings from the copies that remain.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225460 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 18:52:15 +00:00
Eric Christopher
2c470a92e2 Make the TargetMachine in MipsSubtarget a reference rather
than a pointer to make unifying code a bit easier.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225459 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 18:18:57 +00:00
Eric Christopher
8ea074b518 Update include - this class doesn't use the target machine, but
only the subtarget.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225458 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 18:18:54 +00:00
Eric Christopher
4ee6e6993f Fix a couple of odd formatting issues.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225457 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 18:18:53 +00:00
Eric Christopher
78a726e36d This routine is in InstrInfo, there's no need to access it again.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225456 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 18:18:50 +00:00
Ahmed Bougacha
3df0ee1141 [X86] Reflow comment. NFC.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225455 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 17:49:48 +00:00
Rafael Espindola
e8d9f7b5d1 clang-format. NFC.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225454 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 16:25:01 +00:00
Rafael Espindola
8aab70ebfe Make this test a bit stricter.
It now checks for the end of the line or the opening '{'.
While at it, remove empty comments.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225451 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 16:11:18 +00:00
Justin Hibbits
77e85a150c Add saving and restoring of r30 to the prologue and epilogue, respectively
Summary: The PIC additions didn't update the prologue and epilogue code to save and restore r30 (PIC base register).  This does that.

Test Plan: Tests updated.

Reviewers: hfinkel

Reviewed By: hfinkel

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D6876

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225450 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 15:47:19 +00:00
Rafael Espindola
f5aa68179c Explicitly handle LinkOnceODRAutoHideLinkage. NFC. We already have a test.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225449 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 15:39:50 +00:00
Rafael Espindola
b67f18b2d8 Update naming style and clang-format. NFC.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225448 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 15:36:32 +00:00
Kristof Beyls
d1cee9b3bc Fix large stack alignment codegen for ARM and Thumb2 targets
This partially fixes PR13007 (ARM CodeGen fails with large stack
alignment): for ARM and Thumb2 targets, but not for Thumb1, as it
seems stack alignment for Thumb1 targets hasn't been supported at
all.

Producing an aligned stack pointer is done by zero-ing out the lower
bits of the stack pointer. The BIC instruction was used for this.
However, the immediate field of the BIC instruction only allows to
encode an immediate that can zero out up to a maximum of the 8 lower
bits. When a larger alignment is requested, a BIC instruction cannot
be used; llvm was silently producing incorrect code in this case.

This commit fixes code generation for large stack aligments by
using the BFC instruction instead, when the BFC instruction is
available.  When not, it uses 2 instructions: a right shift,
followed by a left shift to zero out the lower bits.

The lowering of ARM::Int_eh_sjlj_dispatchsetup still has code
that unconditionally uses BIC to realign the stack pointer, so it
very likely has the same problem. However, I wasn't able to
produce a test case for that. This commit adds an assert so that
the compiler will fail the assert instead of silently generating
wrong code if this is ever reached.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225446 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 15:09:14 +00:00
Tom Stellard
9a6e4f08fe R600/SI: Remove SIISelLowering::legalizeOperands()
Its functionality has been replaced by calling
SIInstrInfo::legalizeOperands() from
SIISelLowering::AdjstInstrPostInstrSelection() and running the
SIFoldOperands and SIShrinkInstructions passes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225445 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 15:08:17 +00:00
Elena Demikhovsky
6e8b53da17 Masked Load/Store - fixed a bug in type legalization.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225441 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 12:29:19 +00:00
Michael Kuperstein
477eba5f81 Fix a think-o in the test for r225438.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225440 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 12:05:02 +00:00
Michael Kuperstein
757d230f7d Fix include ordering, NFC.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225439 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 11:59:43 +00:00
Michael Kuperstein
0858c28ca8 [X86] Don't try to generate direct calls to TLS globals
The call lowering assumes that if the callee is a global, we want to emit a direct call.
This is correct for regular globals, but not for TLS ones.

Differential Revision: http://reviews.llvm.org/D6862

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225438 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 11:50:58 +00:00
Michael Kuperstein
1cea749780 Move SPAdj logic from PEI into the targets (NFC)
PEI tries to keep track of how much starting or ending a call sequence adjusts the stack pointer by, so that it can resolve frame-index references. Currently, it takes a very simplistic view of how SP adjustments are done - both FrameStartOpcode and FrameDestroyOpcode adjust it exactly by the amount written in its first argument.

This view is in fact incorrect for some targets (e.g. due to stack re-alignment, or because it may want to adjust the stack pointer in multiple steps). However, that doesn't cause breakage, because most targets (the only in-tree exception appears to be 32-bit ARM) rely on being able to simplify the call frame pseudo-instructions earlier, so this code is never hit. 

Moving the computation into TargetInstrInfo allows targets to override the way the adjustment is computed if they need to have a non-zero SPAdj.

Differential Revision: http://reviews.llvm.org/D6863

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225437 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 11:04:38 +00:00
Craig Topper
cb964a5c58 Fix test case I missed in r225432.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225434 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 07:57:27 +00:00
Craig Topper
367b67df3e [X86] Don't print 'dword ptr' or 'qword ptr' on the operand to some of the LEA variants in Intel syntax. The memory operand is inherently unsized.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225432 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 07:41:30 +00:00
Adrian Prantl
7e44a65e6b Revert "Reapply: Teach SROA how to update debug info for fragmented variables."
This reverts commit r225379 while investigating an assertion failure reported
by Alexey.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225424 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 02:02:00 +00:00
Quentin Colombet
9d60e0ff0a [RegAllocGreedy] Introduce a late pass to repair broken hints.
A broken hint is a copy where both ends are assigned different colors. When a
variable gets evicted in the neighborhood of such copies, it is likely we can
reconcile some of them.


** Context **

Copies are inserted during the register allocation via splitting. These split
points are required to relax the constraints on the allocation problem. When
such a point is inserted, both ends of the copy would not share the same color
with respect to the current allocation problem. When variables get evicted,
the allocation problem becomes different and some split point may not be
required anymore. However, the related variables may already have been colored.

This usually shows up in the assembly with pattern like this:
def A
...
save A to B
def A
use A
restore A from B
...
use B

Whereas we could simply have done:
def B
...
def A
use A
...
use B


** Proposed Solution **

A variable having a broken hint is marked for late recoloring if and only if
selecting a register for it evict another variable. Indeed, if no eviction
happens this is pointless to look for recoloring opportunities as it means the
situation was the same as the initial allocation problem where we had to break
the hint.

Finally, when everything has been allocated, we look for recoloring
opportunities for all the identified candidates.
The recoloring is performed very late to rely on accurate copy cost (all
involved variables are allocated).
The recoloring is simple unlike the last change recoloring. It propagates the
color of the broken hint to all its copy-related variables. If the color is
available for them, the recoloring uses it, otherwise it gives up on that hint
even if a more complex coloring would have worked.

The recoloring happens only if it is profitable. The profitability is evaluated
using the expected frequency of the copies of the currently recolored variable
with a) its current color and b) with the target color. If a) is greater or
equal than b), then it is profitable and the recoloring happen.


** Example **

Consider the following example:
BB1:
  a =
  b =
BB2:
  ...
   = b
   = a
Let us assume b gets split:
BB1:
  a =
  b =
BB2:
  c = b
  ...
  d = c
  = d
  = a
Because of how the allocation work, b, c, and d may be assigned different
colors. Now, if a gets evicted to make room for c, assuming b and d were
assigned to something different than a.
We end up with:
BB1:
  a =
  st a, SpillSlot
  b =
BB2:
  c = b
  ...
  d = c
  = d
  e = ld SpillSlot
  = e
This is likely that we can assign the same register for b, c, and d,
getting rid of 2 copies.


** Performances **

Both ARM64 and x86_64 show performance improvements of up to 3% for the
llvm-testsuite + externals with Os and O3. There are a few regressions too that
comes from the (in)accuracy of the block frequency estimate.

<rdar://problem/18312047>


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225422 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 01:16:39 +00:00
Ahmed Bougacha
7fac1d945f [SelectionDAG] Allow targets to specify legality of extloads' result
type (in addition to the memory type).

The *LoadExt* legalization handling used to only have one type, the
memory type.  This forced users to assume that as long as the extload
for the memory type was declared legal, and the result type was legal,
the whole extload was legal.

However, this isn't always the case.  For instance, on X86, with AVX,
this is legal:
    v4i32 load, zext from v4i8
but this isn't:
    v4i64 load, zext from v4i8
Whereas v4i64 is (arguably) legal, even without AVX2.

Note that the same thing was done a while ago for truncstores (r46140),
but I assume no one needed it yet for extloads, so here we go.

Calls to getLoadExtAction were changed to add the value type, found
manually in the surrounding code.

Calls to setLoadExtAction were mechanically changed, by wrapping the
call in a loop, to match previous behavior.  The loop iterates over
the MVT subrange corresponding to the memory type (FP vectors, etc...).
I also pulled neighboring setTruncStoreActions into some of the loops;
those shouldn't make a difference, as the additional types are illegal.
(e.g., i128->i1 truncstores on PPC.)

No functional change intended.

Differential Revision: http://reviews.llvm.org/D6532


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225421 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 00:51:32 +00:00
Nick Lewycky
f411a8dd29 Remove empty statement. No functionality change.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225420 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 00:47:03 +00:00
Matthias Braun
e081880cc1 X86: VZeroUpperInserter: shortcut should not trigger if we have any function live-ins.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225419 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 00:33:48 +00:00
Kevin Enderby
a217f983d6 Run clang-format on tools/llvm-objdump/MachODump.cpp again as some of my
previous changes got in with incorrect formatting. No functional change.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225417 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 00:25:24 +00:00
Matthias Braun
9f6a38fc70 RegisterCoalescer: Do not remove IMPLICIT_DEFS if they are required for subranges.
The register coalescer used to remove implicit_defs when they are
covered by the main range anyway. With subreg liveness tracking we can't
do that anymore in places where the IMPLICIT_DEF is required as begin of
a subregister liverange.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225416 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-08 00:21:23 +00:00
Matthias Braun
a065cf13cd RegisterCoalescer: Fix valuesIdentical() in some subrange merge cases.
I got confused and assumed SrcIdx/DstIdx of the CoalescerPair is a
subregister index in SrcReg/DstReg, but they are actually subregister
indices of the coalesced register that get you back to SrcReg/DstReg
when applied.

Fixed the bug, improved comments and simplified code accordingly.

Testcase by Tom Stellard!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225415 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-07 23:58:38 +00:00
Matthias Braun
b6eccdd6b0 LiveInterval: Implement feedback by Quentin Colombet.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225413 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-07 23:35:11 +00:00
Philip Reames
a7f8f932a6 [GC] improve testing around gc.relocate and fix a test
Patch by: Ramkumar Ramachandra <artagnon@gmail.com>

"This patch started out as an exploration of gc.relocate, and an attempt
to write a simple test in call-lowering. I then noticed that the
arguments of gc.relocate were not checked fully, so I went in and fixed
a few things. Finally, the most important outcome of this patch is that
my new error handling code caught a bug in a callsite in
stackmap-format."

Differential Revision: http://reviews.llvm.org/D6824



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225412 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-07 22:48:01 +00:00
Ahmed Bougacha
a84b573c98 [CodeGen] Add MVT::isValid to replace manual validity checks. NFC.
Now that we have MVT::FIRST_VALUETYPE (r225362), we can provide a method
checking that the MVT is valid, that is, it's in
  [FIRST_VALUETYPE, LAST_VALUETYPE[.
This commit also uses it in a few asserts, that would previously accept
invalid MVTs, such as the default constructed -1.  In that case,
the code following those asserts would do an out-of-bounds array access.
Using MVT::isValid, those assertions fail as expected when passed
invalid MVTs.
It feels clunky to have such a validity checking function, but it's
at least better than the alternative of broken manual checks.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225411 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-07 22:47:46 +00:00
Tom Stellard
a36b682c17 R600/SI: Commute instructions to enable more folding opportunities
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225410 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-07 22:44:19 +00:00
Duncan P. N. Exon Smith
727176d00e IR: Add MDNode::getDistinct()
Allow distinct `MDNode`s to be explicitly created.  There's no way (yet)
of representing their distinctness in assembly/bitcode, however, so this
still isn't first-class.

Part of PR22111.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225406 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-07 22:24:46 +00:00
Tom Stellard
a3ee583339 R600/SI: Only fold immediates that have one use
Folding the same immediate into multiple instruction will increase
program size, which can hurt performance.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225405 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-07 22:18:27 +00:00
Sean Silva
d17010f84d Test commit.
Hopefully this one won't kill the git mirror...

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225404 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-07 22:07:33 +00:00
Duncan P. N. Exon Smith
ee06e126b7 IR: Add MDNode::isDistinct()
Add API to indicate whether an `MDNode` is distinct.  A distinct node is
not stored in the MDNode uniquing tables, and will never be returned by
`MDNode::get()`.

Although distinct nodes are only currently created by uniquing
collisions (when operands change), PR22111 will allow these nodes to be
explicitly created.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225401 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-07 21:35:38 +00:00
Sean Silva
699e5d7bc9 [LangRef] PR22118: Hyphen is allowed in IR identifiers.
E.g. %-foo and %fo-o.

Thanks to eagle-eyed reporter Tomas Brukner.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225400 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-07 21:35:14 +00:00
Adrian Prantl
31208c1591 Update a comment.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225399 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-07 21:35:13 +00:00
Duncan P. N. Exon Smith
c742e3a68d Linker: Don't use MDNode::replaceOperandWith()
`MDNode::replaceOperandWith()` changes all instances of metadata.  Stop
using it when linking module flags, since (due to uniquing) the flag
values could be used by other metadata.

Instead, use new API `NamedMDNode::setOperand()` to update the reference
directly.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225397 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-07 21:32:27 +00:00
Alexey Samsonov
ec1494b99f XFAIL several MCJIT EH tests under ASan and MSan bootstrap.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225393 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-07 21:27:26 +00:00
Ahmed Bougacha
8065738154 [CodeGen] Use MVT iterator_ranges in legality loops. NFC intended.
A few loops do trickier things than just iterating on an MVT subset,
so I'll leave them be for now.
Follow-up of r225387.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225392 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-07 21:27:10 +00:00