Ping 3: Add a LOAD_SEQUENCE_POINT ISDOpcode
Evan Cheng
evan.cheng at apple.com
Fri Dec 6 09:14:33 PST 2013
On Dec 6, 2013, at 1:24 AM, Richard Sandiford <rsandifo at linux.vnet.ibm.com> wrote:
> Evan Cheng <evan.cheng at apple.com> writes:
>> On Dec 5, 2013, at 3:07 AM, Richard Sandiford
>> <rsandifo at linux.vnet.ibm.com> wrote:
>>
>>> Hi Evan,
>>>
>>> Thanks for the review.
>>>
>>> Evan Cheng <evan.cheng at apple.com> writes:
>>>> I'm not very comfortable with adding a generic opcode. Can't you use a
>>>> target specific intrinsic?
>>>
>>> If the opcode's out, is it still OK to have a TargetLowering hook that
>>> gets called before atomic and volatile loads, as in the patch below?
>>> This replaces the getInsertLoadSequencePoints() function from the first
>>> patch but should be a bit more general (and hopefully a bit more intuitive,
>>> since it's named after the situations in which it's used).
>>
>> Ideally I'd like to see the code for dealing with these loads in the
>> target specific isel lowering code. Until we have other targets needing
>> similar features, it's a bit difficult to understand whether a opcode
>> and / or target hooks are needed. Do you think that's possible?
>
> I think doing it in LowerOperation() means that either (a) we just
> insert a serialiasing instruction before the load or (b) we also replace
> the load with a different representation, to indicate that it's properly
> protected by a serialising instruction.
>
> The problem with (a) is that the meaning of a volatile load node then
> depends on whether we're looking at it before or after lowering. It seems
> bad to have that kind of phase-dependent interpretation.
>
> The problem with (b) is that, once protected, the load really is just
> a normal load. The architecture has many register-memory instructions
> and I think it would be quite difficult to go through and make sure
> that everything that handles memory operands is also able to handle the
> lowered form.
I'm not sure if I completely follow you. But if the concern is to distinguish the loads, would it be cleaner to add a property to MemSDNode? And is this property related to SynchronizationScope property that's already on MemSDNode?
Evan
>
>> If not, then target hook might be acceptable. But I haven't had the time
>> to think this through or review your patch fully.
>
> Thanks. FWIW, although the patch is quite long, only the first four hunks
> are target-independent:
>
> diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
> index 6f643c3..7bc3a52 100644
> --- a/include/llvm/Target/TargetLowering.h
> +++ b/include/llvm/Target/TargetLowering.h
> @@ -2082,6 +2082,18 @@ public:
> return NULL;
> }
>
> + /// This callback is used to prepare for a volatile or atomic load.
> + /// It takes a chain node as input and returns the chain for the load itself.
> + ///
> + /// Having a callback like this is necessary for targets like SystemZ,
> + /// which allows a CPU to reuse the result of a previous load indefinitely,
> + /// even if a cache-coherent store is performed by another CPU. The defalut
> + /// implementation does nothing.
> + virtual SDValue prepareVolatileOrAtomicLoad(SDValue Chain, SDLoc DL,
> + SelectionDAG &DAG) const {
> + return Chain;
> + }
> +
> /// This callback is invoked by the type legalizer to legalize nodes with an
> /// illegal operand type but legal result types. It replaces the
> /// LowerOperation callback in the type Legalizer. The reason we can not do
> diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> index b1d247e..071781a 100644
> --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> @@ -3400,7 +3400,7 @@ void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
>
> SDValue Root;
> bool ConstantMemory = false;
> - if (I.isVolatile() || NumValues > MaxParallelChains)
> + if (isVolatile || NumValues > MaxParallelChains)
> // Serialize volatile loads with other side effects.
> Root = getRoot();
> else if (AA->pointsToConstantMemory(
> @@ -3413,6 +3413,10 @@ void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
> Root = DAG.getRoot();
> }
>
> + const TargetLowering *TLI = TM.getTargetLowering();
> + if (isVolatile)
> + Root = TLI->prepareVolatileOrAtomicLoad(Root, getCurSDLoc(), DAG);
> +
> SmallVector<SDValue, 4> Values(NumValues);
> SmallVector<SDValue, 4> Chains(std::min(unsigned(MaxParallelChains),
> NumValues));
> @@ -3637,6 +3641,7 @@ void SelectionDAGBuilder::visitAtomicLoad(const LoadInst &I) {
> if (I.getAlignment() < VT.getSizeInBits() / 8)
> report_fatal_error("Cannot generate unaligned atomic load");
>
> + InChain = TLI->prepareVolatileOrAtomicLoad(InChain, dl, DAG);
> SDValue L =
> DAG.getAtomic(ISD::ATOMIC_LOAD, dl, VT, VT, InChain,
> getValue(I.getPointerOperand()),
>
> The rest are all local to the target.
>
> Thanks,
> Richard
>
More information about the llvm-commits
mailing list