From: Christopher Lamb Date: Sat, 21 Apr 2007 08:16:25 +0000 (+0000) Subject: add support for alignment attributes on load/store instructions X-Git-Tag: android-x86-6.0-r1~1003^2~35339 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=2330e4d4c4f8008d17f5a38ac0d7b04e139d4131;p=android-x86%2Fexternal-llvm.git add support for alignment attributes on load/store instructions git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36301 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/CREDITS.TXT b/CREDITS.TXT index 58cc043ac2c..fe0b4fe68ae 100644 --- a/CREDITS.TXT +++ b/CREDITS.TXT @@ -118,6 +118,10 @@ N: Sumant Kowshik E: kowshik@uiuc.edu D: Author of the original C backend +N: Christopher Lamb +E: christopher.lamb@gmail.com +D: aligned load/store support + N: Jim Laskey E: jlaskey@apple.com D: Improvements to the PPC backend, instruction scheduling diff --git a/docs/BytecodeFormat.html b/docs/BytecodeFormat.html index 8cb072bb9d4..56fc0afce9c 100644 --- a/docs/BytecodeFormat.html +++ b/docs/BytecodeFormat.html @@ -1587,15 +1587,15 @@ possible.

Call+FastCC+TailCall5951.5 Call+FastCC6051.5 Call+CCC+TailCall6151.5 - Load+Volatile6231.3 - Store+Volatile6331.3 + Load+Attributes6272.0 + Store+Attributes6372.0

* Note: These aren't really opcodes from an LLVM language perspective. They encode information into other opcodes without reserving space for that information. -For example, opcode=63 is a Volatile Store. The opcode for this +For example, opcode=63 is an Attributed Store. The opcode for this instruction is 25 (Store) but we encode it as 63 to indicate that is a Volatile Store. The same is done for the calling conventions and tail calls. In each of these entries in range 56-63, the opcode is documented as the base diff --git a/docs/LangRef.html b/docs/LangRef.html index 057fb9cdf80..c615bb3c501 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -2609,7 +2609,7 @@ instructions), the memory is reclaimed.

Instruction
Syntax:
-
  <result> = load <ty>* <pointer>
<result> = volatile load <ty>* <pointer>
+
  <result> = load <ty>* <pointer>[, align <alignment>]
<result> = volatile load <ty>* <pointer>[, align <alignment>]
Overview:

The 'load' instruction is used to read from memory.

Arguments:
@@ -2634,8 +2634,8 @@ instructions.

Instruction
Syntax:
-
  store <ty> <value>, <ty>* <pointer>                   ; yields {void}
-  volatile store <ty> <value>, <ty>* <pointer>                   ; yields {void}
+
  store <ty> <value>, <ty>* <pointer>[, align <alignment>]                   ; yields {void}
+  volatile store <ty> <value>, <ty>* <pointer>[, align <alignment>]          ; yields {void}
 
Overview:

The 'store' instruction is used to write to memory.

diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 0f17e6993ad..9d8024b86d4 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -311,10 +311,12 @@ public: /// determined by their operands, and they produce a value AND a token chain. /// SDOperand getLoad(MVT::ValueType VT, SDOperand Chain, SDOperand Ptr, - const Value *SV, int SVOffset, bool isVolatile=false); + const Value *SV, int SVOffset, bool isVolatile=false, + unsigned Alignment=0); SDOperand getExtLoad(ISD::LoadExtType ExtType, MVT::ValueType VT, SDOperand Chain, SDOperand Ptr, const Value *SV, - int SVOffset, MVT::ValueType EVT, bool isVolatile=false); + int SVOffset, MVT::ValueType EVT, bool isVolatile=false, + unsigned Alignment=0); SDOperand getIndexedLoad(SDOperand OrigLoad, SDOperand Base, SDOperand Offset, ISD::MemIndexedMode AM); SDOperand getVecLoad(unsigned Count, MVT::ValueType VT, SDOperand Chain, @@ -323,10 +325,11 @@ public: /// getStore - Helper function to build ISD::STORE nodes. /// SDOperand getStore(SDOperand Chain, SDOperand Val, SDOperand Ptr, - const Value *SV, int SVOffset, bool isVolatile=false); + const Value *SV, int SVOffset, bool isVolatile=false, + unsigned Alignment=0); SDOperand getTruncStore(SDOperand Chain, SDOperand Val, SDOperand Ptr, const Value *SV, int SVOffset, MVT::ValueType TVT, - bool isVolatile=false); + bool isVolatile=false, unsigned Alignment=0); SDOperand getIndexedStore(SDOperand OrigStoe, SDOperand Base, SDOperand Offset, ISD::MemIndexedMode AM); diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 77d607a2cb6..f617800d038 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -1448,7 +1448,7 @@ protected: friend class SelectionDAG; LoadSDNode(SDOperand *ChainPtrOff, SDVTList VTs, ISD::MemIndexedMode AM, ISD::LoadExtType ETy, MVT::ValueType LVT, - const Value *SV, int O=0, unsigned Align=1, bool Vol=false) + const Value *SV, int O=0, unsigned Align=0, bool Vol=false) : SDNode(ISD::LOAD, VTs), AddrMode(AM), ExtType(ETy), LoadedVT(LVT), SrcValue(SV), SVOffset(O), Alignment(Align), IsVolatile(Vol) { @@ -1456,6 +1456,7 @@ protected: Ops[1] = ChainPtrOff[1]; // Ptr Ops[2] = ChainPtrOff[2]; // Off InitOperands(Ops, 3); + assert(Align != 0 && "Loads should have non-zero aligment"); assert((getOffset().getOpcode() == ISD::UNDEF || AddrMode != ISD::UNINDEXED) && "Only indexed load has a non-undef offset operand"); @@ -1518,6 +1519,7 @@ protected: Ops[2] = ChainValuePtrOff[2]; // Ptr Ops[3] = ChainValuePtrOff[3]; // Off InitOperands(Ops, 4); + assert(Align != 0 && "Stores should have non-zero aligment"); assert((getOffset().getOpcode() == ISD::UNDEF || AddrMode != ISD::UNINDEXED) && "Only indexed store has a non-undef offset operand"); diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 2387739720c..0a61d120c25 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -211,9 +211,11 @@ public: /// SubclassData field in Value to store whether or not the load is volatile. /// class LoadInst : public UnaryInstruction { + LoadInst(const LoadInst &LI) : UnaryInstruction(LI.getType(), Load, LI.getOperand(0)) { setVolatile(LI.isVolatile()); + setAlignment(LI.getAlignment()); #ifndef NDEBUG AssertOK(); @@ -223,14 +225,16 @@ class LoadInst : public UnaryInstruction { public: LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBefore); LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAtEnd); - LoadInst(Value *Ptr, const std::string &Name, bool isVolatile = false, + LoadInst(Value *Ptr, const std::string &Name, bool isVolatile = false, + Instruction *InsertBefore = 0); + LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, unsigned Align, Instruction *InsertBefore = 0); LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, BasicBlock *InsertAtEnd); LoadInst(Value *Ptr, const char *Name, Instruction *InsertBefore); LoadInst(Value *Ptr, const char *Name, BasicBlock *InsertAtEnd); - explicit LoadInst(Value *Ptr, const char *Name = 0, bool isVolatile = false, + explicit LoadInst(Value *Ptr, const char *Name = 0, bool isVolatile = false, Instruction *InsertBefore = 0); LoadInst(Value *Ptr, const char *Name, bool isVolatile, BasicBlock *InsertAtEnd); @@ -238,14 +242,23 @@ public: /// isVolatile - Return true if this is a load from a volatile memory /// location. /// - bool isVolatile() const { return SubclassData; } + bool isVolatile() const { return SubclassData & 1; } /// setVolatile - Specify whether this is a volatile load or not. /// - void setVolatile(bool V) { SubclassData = V; } + void setVolatile(bool V) { SubclassData = (SubclassData & ~1) | (V) ? 1 : 0; } virtual LoadInst *clone() const; + /// getAlignment - Return the alignment of the access that is being performed + /// + unsigned getAlignment() const { + signed Log2AlignVal = ((SubclassData>>1)-1); + return ((Log2AlignVal < 0) ? 0 : 1<>1)-1); + return ((Log2AlignVal < 0) ? 0 : 1<