[llvm-commits] [llvm] r50279 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/Transforms/Scalar/CodeGenPrepare.cpp test/CodeGen/Generic/multiple-return-values-cross-block-with-invoke.ll
Dan Gohman
gohman at apple.com
Mon Apr 28 11:41:28 PDT 2008
On Apr 28, 2008, at 12:13 AM, Chris Lattner wrote:
> On Apr 25, 2008, at 11:27 AM, Dan Gohman wrote:
>>
>> /// RegsForValue - This struct represents the physical registers
>> that a
>> /// particular value is assigned and the type information about
>> the value.
>> /// This is needed because values can be promoted into larger
>> registers and
>> /// expanded into multiple smaller registers than the value.
>> struct VISIBILITY_HIDDEN RegsForValue {
>
> This should probably explicitly mention how it handles aggregates.
> Maybe a good general summary up front could help my larger complaint
> next:
I rewrote this comment. Let me know if have further questions.
>
>
>
> ...
>
>> + /// RegVTs - The value types of the registers. This is the same
>> size
>> + /// as ValueVTs; every register contributing to a given value
>> must
>> + /// have the same type. When Regs contains all virtual
>> registers, the
>> + /// contents of RegVTs is redundant with TLI's getRegisterType
>> member
>> + /// function, however when Regs contains physical registers, it
>> is
>> + /// necessary to have a separate record of the types.
>> ///
>> + SmallVector<MVT::ValueType, 4> RegVTs;
>>
>> + /// ValueVTs - The value types of the values, which may be
>> promoted
>> + /// or synthesized from one or more registers.
>> + SmallVector<MVT::ValueType, 4> ValueVTs;
>
> The descriptions of these fields is not very clear to me. The
> description of RegVTs forward references ValueVTs, maybe ValueVTs
> should be moved first? It would be helpful to have an explanatory
> comment here with an example. For example, on PPC, how is {i8, i64}
> handled by these two vectors? Maybe 'Regs' should have a comment that
> indicates it can contain pregs?
I rewrote several related comments to be more explanatory.
>
>
>>
>> +
>> + RegsForValue() : TLI(0) {}
>> +
>> + RegsForValue(const TargetLowering &tli,
>> + unsigned Reg, MVT::ValueType regvt, MVT::ValueType
>> valuevt)
>> + : TLI(&tli), Regs(1, Reg), RegVTs(1, regvt), ValueVTs(1,
>> valuevt) {}
>> + RegsForValue(const TargetLowering &tli,
>> + const std::vector<unsigned> ®s,
>> MVT::ValueType regvt, MVT::ValueType valuevt)
>> + : TLI(&tli), Regs(regs), RegVTs(1, regvt), ValueVTs(1,
>> valuevt) {}
>> + RegsForValue(const TargetLowering &tli,
>> + const std::vector<unsigned> ®s,
>> + const SmallVector<MVT::ValueType, 4> ®vts,
>> + const SmallVector<MVT::ValueType, 4> &valuevts)
>> + : TLI(&tli), Regs(regs), RegVTs(regvts), ValueVTs(valuevts) {}
>> + RegsForValue(const TargetLowering &tli,
>> + unsigned Reg, const Type *Ty) : TLI(&tli) {
>
> So many ctors... would it be reasonable to change clients to use one
> of the more general ones instead of having so many ctors?
One of them was unused; I deleted it.
>
>
>>
>> + ComputeValueVTs(tli, Ty, ValueVTs);
>> +
>> + for (unsigned Value = 0; Value != ValueVTs.size(); ++Value) {
>
> Please add a comment explaining what this loop is doing. Does
> 'ValueVTs.size()' need to be recomputed on every iteration?
No, it ought to be inlined :-). I fixed it though.
>
>
>>
>> + MVT::ValueType ValueVT = ValueVTs[Value];
>> + unsigned NumRegs = TLI->getNumRegisters(ValueVT);
>> + MVT::ValueType RegisterVT = TLI->getRegisterType(ValueVT);
>> + for (unsigned i = 0; i != NumRegs; ++i)
>> + Regs.push_back(Reg + i);
>> + RegVTs.push_back(RegisterVT);
>> + Reg += NumRegs;
>> + }
>> }
>
>
>> @@ -310,16 +362,22 @@
>> /// the correctly promoted or expanded types. Assign these registers
>> /// consecutive vreg numbers and return the first assigned number.
>> unsigned FunctionLoweringInfo::CreateRegForValue(const Value *V) {
>> + const Type *Ty = V->getType();
>> + SmallVector<MVT::ValueType, 4> ValueVTs;
>> + ComputeValueVTs(TLI, Ty, ValueVTs);
>> +
>> + unsigned FirstReg = 0;
>> + for (unsigned Value = 0; Value != ValueVTs.size(); ++Value) {
>> + MVT::ValueType ValueVT = ValueVTs[Value];
>> + unsigned NumRegs = TLI.getNumRegisters(ValueVT);
>> + MVT::ValueType RegisterVT = TLI.getRegisterType(ValueVT);
>>
>> + for (unsigned i = 0; i != NumRegs; ++i) {
>> + unsigned R = MakeReg(RegisterVT);
>> + if (!FirstReg) FirstReg = R;
>> + }
>> + }
>> + return FirstReg;
>> }
>
> The comments in this method should be improved to talk about what it
> is now doing. Please mention aggregates. Could this code change to
> use RegsForValue to compute the expansion? Maybe it should be a new
> method on RegsForValue?
I added a comment that mentions aggregates. This code does
use ComputeValueVTs to do most of the work; that's a function
I factored out specifically for the purpose of using it
in both CreateRegForValue and RegsForValue.
>
>
>> @@ -3898,8 +3985,9 @@
>> if ((NumOps & 7) == 2 /*REGDEF*/) {
>> // Add NumOps>>3 registers to MatchedRegs.
>> RegsForValue MatchedRegs;
>> - MatchedRegs.ValueVT = InOperandVal.getValueType();
>> - MatchedRegs.RegVT = AsmNodeOperands[CurOp
>> +1].getValueType();
>> + MatchedRegs.TLI = &TLI;
>> + MatchedRegs.ValueVTs.resize(1,
>> InOperandVal.getValueType());
>> + MatchedRegs.RegVTs.resize(1, AsmNodeOperands[CurOp
>> +1].getValueType());
>
> Please use push_back, instead of resize(1, x)
I used resize because it's initializing the vector contents
with exactly one element. But I'll change it if you insist :-).
>
>
>> @@ -4304,21 +4392,14 @@
>> }
>>
>> // Figure out the result value types. We start by making a list of
>> + // the potentially illegal return value types.
>> SmallVector<MVT::ValueType, 4> LoweredRetTys;
>> SmallVector<MVT::ValueType, 4> RetTys;
>> + ComputeValueVTs(*this, RetTy, RetTys);
>>
>> + // Then we translate that to a list of legal types.
>> + for (unsigned I = 0, E = RetTys.size(); I != E; ++I) {
>> + MVT::ValueType VT = RetTys[I];
>> MVT::ValueType RegisterVT = getRegisterType(VT);
>> unsigned NumRegs = getNumRegisters(VT);
>> for (unsigned i = 0; i != NumRegs; ++i)
>
> This seems like something that should be a method on RegsForValue.
It isn't trivial to do though. I expect we'll continue to
refactor RegsForValue and eventually get this cleaned up.
>
>
>> @@ -4441,19 +4522,11 @@
>> cast<RegisterSDNode>(Op.getOperand(1))->getReg() != Reg) &&
>> "Copy from a reg to the same reg!");
>> assert(!TargetRegisterInfo::isPhysicalRegister(Reg) && "Is a
>> physreg");
>> + RegsForValue RFV(TLI, Reg, V->getType());
>> + SDOperand Chain = DAG.getEntryNode();
>> + RFV.getCopyToRegs(Op, DAG, Chain, 0);
>> + PendingExports.push_back(Chain);
>> }
>
> I'm not sure if your patch is responsible, but it is very strange to
> me that RegsForValue::getCopyToRegs takes 'Chain' byref and mutates
> the input. Should RegsForValue::getCopyToRegs return a new chain
> instead?
Perhaps, but currently the Chain handling is consistent with
the optional Flag handling.
Dan
More information about the llvm-commits
mailing list