[llvm] r174973 - Hexagon: Add support to generate predicated absolute addressing mode

Anshuman Dasgupta adasgupt at codeaurora.org
Tue Feb 12 09:00:23 PST 2013


Jyotsna,

This patch needs a few minor edits:

+  if (needShift)
+  {

Remove curly braces

+      else if (MO.isImm()) {
+        MI->getOperand(oper+1).ChangeToImmediate(MO.getImm());
+      }

No curly braces here. There are a few other if/else if statements that 
should not have braces either.

+      else {
+        assert(false && "Unexpected operand type");
+      }


Please replace with llvm_unreachable() and remove curly braces.

Thanks
-Anshu


---
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
hosted by The Linux Foundation





On 2/12/2013 10:06 AM, Jyotsna Verma wrote:
> Author: jverma
> Date: Tue Feb 12 10:06:23 2013
> New Revision: 174973
>
> URL: http://llvm.org/viewvc/llvm-project?rev=174973&view=rev
> Log:
> Hexagon: Add support to generate predicated absolute addressing mode
> instructions.
>
>
> Added:
>      llvm/trunk/test/CodeGen/Hexagon/pred-absolute-store.ll
> Modified:
>      llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp
>
> Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp?rev=174973&r1=174972&r2=174973&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp (original)
> +++ llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp Tue Feb 12 10:06:23 2013
> @@ -2237,38 +2237,141 @@ PredicateInstruction(MachineInstr *MI,
>     assert (isPredicable(MI) && "Expected predicable instruction");
>     bool invertJump = (!Cond.empty() && Cond[0].isImm() &&
>                        (Cond[0].getImm() == 0));
> +
> +  // This will change MI's opcode to its predicate version.
> +  // However, its operand list is still the old one, i.e. the
> +  // non-predicate one.
>     MI->setDesc(get(getMatchingCondBranchOpcode(Opc, invertJump)));
> -  //
> -  // This assumes that the predicate is always the first operand
> -  // in the set of inputs.
> -  //
> -  MI->addOperand(MI->getOperand(MI->getNumOperands()-1));
> -  int oper;
> -  for (oper = MI->getNumOperands() - 3; oper >= 0; --oper) {
> -    MachineOperand MO = MI->getOperand(oper);
> -    if ((MO.isReg() && !MO.isUse() && !MO.isImplicit())) {
> -      break;
> -    }
>   
> -    if (MO.isReg()) {
> -      MI->getOperand(oper+1).ChangeToRegister(MO.getReg(), MO.isDef(),
> -                                              MO.isImplicit(), MO.isKill(),
> -                                              MO.isDead(), MO.isUndef(),
> -                                              MO.isDebug());
> -    } else if (MO.isImm()) {
> -      MI->getOperand(oper+1).ChangeToImmediate(MO.getImm());
> -    } else {
> -      llvm_unreachable("Unexpected operand type");
> +  int oper = -1;
> +  unsigned int GAIdx = 0;
> +
> +  // Indicates whether the current MI has a GlobalAddress operand
> +  bool hasGAOpnd = false;
> +  std::vector<MachineOperand> tmpOpnds;
> +
> +  // Indicates whether we need to shift operands to right.
> +  bool needShift = true;
> +
> +  // The predicate is ALWAYS the FIRST input operand !!!
> +  if (MI->getNumOperands() == 0) {
> +    // The non-predicate version of MI does not take any operands,
> +    // i.e. no outs and no ins. In this condition, the predicate
> +    // operand will be directly placed at Operands[0]. No operand
> +    // shift is needed.
> +    // Example: BARRIER
> +    needShift = false;
> +    oper = -1;
> +  }
> +  else if (   MI->getOperand(MI->getNumOperands()-1).isReg()
> +           && MI->getOperand(MI->getNumOperands()-1).isDef()
> +           && !MI->getOperand(MI->getNumOperands()-1).isImplicit()) {
> +    // The non-predicate version of MI does not have any input operands.
> +    // In this condition, we extend the length of Operands[] by one and
> +    // copy the original last operand to the newly allocated slot.
> +    // At this moment, it is just a place holder. Later, we will put
> +    // predicate operand directly into it. No operand shift is needed.
> +    // Example: r0=BARRIER (this is a faked insn used here for illustration)
> +    MI->addOperand(MI->getOperand(MI->getNumOperands()-1));
> +    needShift = false;
> +    oper = MI->getNumOperands() - 2;
> +  }
> +  else {
> +    // We need to right shift all input operands by one. Duplicate the
> +    // last operand into the newly allocated slot.
> +    MI->addOperand(MI->getOperand(MI->getNumOperands()-1));
> +  }
> +
> +  if (needShift)
> +  {
> +    // Operands[ MI->getNumOperands() - 2 ] has been copied into
> +    // Operands[ MI->getNumOperands() - 1 ], so we start from
> +    // Operands[ MI->getNumOperands() - 3 ].
> +    // oper is a signed int.
> +    // It is ok if "MI->getNumOperands()-3" is -3, -2, or -1.
> +    for (oper = MI->getNumOperands() - 3; oper >= 0; --oper)
> +    {
> +      MachineOperand &MO = MI->getOperand(oper);
> +
> +      // Opnd[0] Opnd[1] Opnd[2] Opnd[3] Opnd[4]   Opnd[5]   Opnd[6]   Opnd[7]
> +      // <Def0>  <Def1>  <Use0>  <Use1>  <ImpDef0> <ImpDef1> <ImpUse0> <ImpUse1>
> +      //               /\~
> +      //              /||\~
> +      //               ||
> +      //        Predicate Operand here
> +      if (MO.isReg() && !MO.isUse() && !MO.isImplicit()) {
> +        break;
> +      }
> +      if (MO.isReg()) {
> +        MI->getOperand(oper+1).ChangeToRegister(MO.getReg(), MO.isDef(),
> +                                                MO.isImplicit(), MO.isKill(),
> +                                                MO.isDead(), MO.isUndef(),
> +                                                MO.isDebug());
> +      }
> +      else if (MO.isImm()) {
> +        MI->getOperand(oper+1).ChangeToImmediate(MO.getImm());
> +      }
> +      else if (MO.isGlobal()) {
> +        // MI can not have more than one GlobalAddress operand.
> +        assert(hasGAOpnd == false && "MI can only have one GlobalAddress opnd");
> +
> +        // There is no member function called "ChangeToGlobalAddress" in the
> +        // MachineOperand class (not like "ChangeToRegister" and
> +        // "ChangeToImmediate"). So we have to remove them from Operands[] list
> +        // first, and then add them back after we have inserted the predicate
> +        // operand. tmpOpnds[] is to remember these operands before we remove
> +        // them.
> +        tmpOpnds.push_back(MO);
> +
> +        // Operands[oper] is a GlobalAddress operand;
> +        // Operands[oper+1] has been copied into Operands[oper+2];
> +        hasGAOpnd = true;
> +        GAIdx = oper;
> +        continue;
> +      }
> +      else {
> +        assert(false && "Unexpected operand type");
> +      }
>       }
>     }
>   
>     int regPos = invertJump ? 1 : 0;
>     MachineOperand PredMO = Cond[regPos];
> +
> +  // [oper] now points to the last explicit Def. Predicate operand must be
> +  // located at [oper+1]. See diagram above.
> +  // This assumes that the predicate is always the first operand,
> +  // i.e. Operands[0+numResults], in the set of inputs
> +  // It is better to have an assert here to check this. But I don't know how
> +  // to write this assert because findFirstPredOperandIdx() would return -1
> +  if (oper < -1) oper = -1;
>     MI->getOperand(oper+1).ChangeToRegister(PredMO.getReg(), PredMO.isDef(),
>                                             PredMO.isImplicit(), PredMO.isKill(),
>                                             PredMO.isDead(), PredMO.isUndef(),
>                                             PredMO.isDebug());
>   
> +  if (hasGAOpnd)
> +  {
> +    unsigned int i;
> +
> +    // Operands[GAIdx] is the original GlobalAddress operand, which is
> +    // already copied into tmpOpnds[0].
> +    // Operands[GAIdx] now stores a copy of Operands[GAIdx-1]
> +    // Operands[GAIdx+1] has already been copied into Operands[GAIdx+2],
> +    // so we start from [GAIdx+2]
> +    for (i = GAIdx + 2; i < MI->getNumOperands(); ++i)
> +      tmpOpnds.push_back(MI->getOperand(i));
> +
> +    // Remove all operands in range [ (GAIdx+1) ... (MI->getNumOperands()-1) ]
> +    // It is very important that we always remove from the end of Operands[]
> +    // MI->getNumOperands() is at least 2 if program goes to here.
> +    for (i = MI->getNumOperands() - 1; i > GAIdx; --i)
> +      MI->RemoveOperand(i);
> +
> +    for (i = 0; i < tmpOpnds.size(); ++i)
> +      MI->addOperand(tmpOpnds[i]);
> +  }
> +
>     return true;
>   }
>   
>
> Added: llvm/trunk/test/CodeGen/Hexagon/pred-absolute-store.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/pred-absolute-store.ll?rev=174973&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/Hexagon/pred-absolute-store.ll (added)
> +++ llvm/trunk/test/CodeGen/Hexagon/pred-absolute-store.ll Tue Feb 12 10:06:23 2013
> @@ -0,0 +1,19 @@
> +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
> +; Check that we are able to predicate instructions with abosolute
> +; addressing mode.
> +
> +; CHECK: if{{ *}}(p{{[0-3]+}}){{ *}}memw(##gvar){{ *}}={{ *}}r{{[0-9]+}}
> +
> + at gvar = external global i32
> +define i32 @test2(i32 %a, i32 %b) nounwind {
> +entry:
> +  %cmp = icmp eq i32 %a, %b
> +  br i1 %cmp, label %if.then, label %if.end
> +
> +if.then:
> +  store i32 %a, i32* @gvar, align 4
> +  br label %if.end
> +
> +if.end:
> +  ret i32 %b
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list