diff options
author | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-05-31 13:25:22 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@linux.vnet.ibm.com> | 2013-05-31 13:25:22 +0000 |
commit | b6606e46abad12a112a57048caec2142522bc67d (patch) | |
tree | 1f4b77d559242b7a3b7a40cd31bf7726206e71bc /lib | |
parent | 5443e7d79044f3198f2da044f1b389b40d9bea6f (diff) | |
download | llvm-b6606e46abad12a112a57048caec2142522bc67d.tar.gz llvm-b6606e46abad12a112a57048caec2142522bc67d.tar.bz2 llvm-b6606e46abad12a112a57048caec2142522bc67d.tar.xz |
[SystemZ] Don't use LOAD and STORE REVERSED for volatile accesses
Unlike most -- hopefully "all other", but I'm still checking -- memory
instructions we support, LOAD REVERSED and STORE REVERSED may access
the memory location several times. This means that they are not suitable
for volatile loads and stores.
This patch is a prerequisite for better atomic load and store support.
The same principle applies there: almost all memory instructions we
support are inherently atomic ("block concurrent"), but LOAD REVERSED
and STORE REVERSED are exceptions.
Other instructions continue to allow volatile operands. I will add
positive "allows volatile" tests at the same time as the "allows atomic
load or store" tests.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@183002 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.td | 15 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZOperators.td | 21 |
2 files changed, 27 insertions, 9 deletions
diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index 062266bb48..c9ec6bc1f9 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -382,13 +382,14 @@ let neverHasSideEffects = 1 in { def LRVGR : UnaryRRE<"lrvgr", 0xB90F, bswap, GR64, GR64>; } -// Byte-swapping loads. -def LRV : UnaryRXY<"lrv", 0xE31E, loadu<bswap>, GR32>; -def LRVG : UnaryRXY<"lrvg", 0xE30F, loadu<bswap>, GR64>; - -// Byte-swapping stores. -def STRV : StoreRXY<"strv", 0xE33E, storeu<bswap>, GR32>; -def STRVG : StoreRXY<"strvg", 0xE32F, storeu<bswap>, GR64>; +// Byte-swapping loads. Unlike normal loads, these instructions are +// allowed to access storage more than once. +def LRV : UnaryRXY<"lrv", 0xE31E, loadu<bswap, nonvolatile_load>, GR32>; +def LRVG : UnaryRXY<"lrvg", 0xE30F, loadu<bswap, nonvolatile_load>, GR64>; + +// Likewise byte-swapping stores. +def STRV : StoreRXY<"strv", 0xE33E, storeu<bswap, nonvolatile_store>, GR32>; +def STRVG : StoreRXY<"strvg", 0xE32F, storeu<bswap, nonvolatile_store>, GR64>; //===----------------------------------------------------------------------===// // Load address instructions diff --git a/lib/Target/SystemZ/SystemZOperators.td b/lib/Target/SystemZ/SystemZOperators.td index 8c4df56b46..ab01b2527a 100644 --- a/lib/Target/SystemZ/SystemZOperators.td +++ b/lib/Target/SystemZ/SystemZOperators.td @@ -142,6 +142,23 @@ def aligned_store : AlignedStore<store>; def aligned_truncstorei16 : AlignedStore<truncstorei16>; def aligned_truncstorei32 : AlignedStore<truncstorei32>; +// Non-volatile loads. Used for instructions that might access the storage +// location multiple times. +class NonvolatileLoad<SDPatternOperator load> + : PatFrag<(ops node:$addr), (load node:$addr), [{ + LoadSDNode *Load = cast<LoadSDNode>(N); + return !Load->isVolatile(); +}]>; +def nonvolatile_load : NonvolatileLoad<load>; + +// Non-volatile stores. +class NonvolatileStore<SDPatternOperator store> + : PatFrag<(ops node:$src, node:$addr), (store node:$src, node:$addr), [{ + StoreSDNode *Store = cast<StoreSDNode>(N); + return !Store->isVolatile(); +}]>; +def nonvolatile_store : NonvolatileStore<store>; + // Insertions. def inserti8 : PatFrag<(ops node:$src1, node:$src2), (or (and node:$src1, -256), node:$src2)>; @@ -186,11 +203,11 @@ def fnabs : PatFrag<(ops node:$ptr), (fneg (fabs node:$ptr))>; // Create a unary operator that loads from memory and then performs // the given operation on it. -class loadu<SDPatternOperator operator> +class loadu<SDPatternOperator operator, SDPatternOperator load = load> : PatFrag<(ops node:$addr), (operator (load node:$addr))>; // Create a store operator that performs the given unary operation // on the value before storing it. -class storeu<SDPatternOperator operator> +class storeu<SDPatternOperator operator, SDPatternOperator store = store> : PatFrag<(ops node:$value, node:$addr), (store (operator node:$value), node:$addr)>; |