diff options
Diffstat (limited to 'lib/Bytecode/Writer/InstructionWriter.cpp')
| -rw-r--r-- | lib/Bytecode/Writer/InstructionWriter.cpp | 58 | 
1 files changed, 38 insertions, 20 deletions
diff --git a/lib/Bytecode/Writer/InstructionWriter.cpp b/lib/Bytecode/Writer/InstructionWriter.cpp index d5a2abf3fb..57012c9df9 100644 --- a/lib/Bytecode/Writer/InstructionWriter.cpp +++ b/lib/Bytecode/Writer/InstructionWriter.cpp @@ -30,7 +30,8 @@ static void outputInstructionFormat0(const Instruction *I, unsigned Opcode,    output_vbr(Type, Out);                         // Result type    unsigned NumArgs = I->getNumOperands(); -  output_vbr(NumArgs + (isa<CastInst>(I) || isa<VarArgInst>(I)), Out); +  output_vbr(NumArgs + (isa<CastInst>(I) || isa<VANextInst>(I) || +                        isa<VAArgInst>(I)), Out);    for (unsigned i = 0; i < NumArgs; ++i) {      int Slot = Table.getSlot(I->getOperand(i)); @@ -38,9 +39,13 @@ static void outputInstructionFormat0(const Instruction *I, unsigned Opcode,      output_vbr((unsigned)Slot, Out);    } -  if (isa<CastInst>(I) || isa<VarArgInst>(I)) { +  if (isa<CastInst>(I) || isa<VAArgInst>(I)) {      int Slot = Table.getSlot(I->getType()); -    assert(Slot != -1 && "Cast/VarArg return type unknown?"); +    assert(Slot != -1 && "Cast return type unknown?"); +    output_vbr((unsigned)Slot, Out); +  } else if (const VANextInst *VAI = dyn_cast<VANextInst>(I)) { +    int Slot = Table.getSlot(VAI->getArgType()); +    assert(Slot != -1 && "VarArg argument type unknown?");      output_vbr((unsigned)Slot, Out);    } @@ -65,29 +70,37 @@ static void outputInstrVarArgsCall(const Instruction *I, unsigned Opcode,    output_vbr(Opcode << 2, Out);                  // Instruction Opcode ID    output_vbr(Type, Out);                         // Result type (varargs type) -  unsigned NumArgs = I->getNumOperands(); -  output_vbr(NumArgs*2, Out); -  // TODO: Don't need to emit types for the fixed types of the varargs function -  // prototype... +  const PointerType *PTy = cast<PointerType>(I->getOperand(0)->getType()); +  const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); +  unsigned NumParams = FTy->getNumParams(); + +  unsigned NumFixedOperands; +  if (isa<CallInst>(I)) { +    // Output an operand for the callee and each fixed argument, then two for +    // each variable argument. +    NumFixedOperands = 1+NumParams; +  } else { +    assert(isa<InvokeInst>(I) && "Not call or invoke??"); +    // Output an operand for the callee and destinations, then two for each +    // variable argument. +    NumFixedOperands = 3+NumParams; +  } +  output_vbr(2 * I->getNumOperands()-NumFixedOperands, Out);    // The type for the function has already been emitted in the type field of the    // instruction.  Just emit the slot # now. -  int Slot = Table.getSlot(I->getOperand(0)); -  assert(Slot >= 0 && "No slot number for value!?!?");       -  output_vbr((unsigned)Slot, Out); - -  // Output a dummy field to fill Arg#2 in the reader that is currently unused -  // for varargs calls.  This is a gross hack to make the code simpler, but we -  // aren't really doing very small bytecode for varargs calls anyways. -  // FIXME in the future: Smaller bytecode for varargs calls -  output_vbr(0, Out); +  for (unsigned i = 0; i != NumFixedOperands; ++i) { +    int Slot = Table.getSlot(I->getOperand(i)); +    assert(Slot >= 0 && "No slot number for value!?!?");       +    output_vbr((unsigned)Slot, Out); +  } -  for (unsigned i = 1; i < NumArgs; ++i) { +  for (unsigned i = NumFixedOperands, e = I->getNumOperands(); i != e; ++i) {      // Output Arg Type ID -    Slot = Table.getSlot(I->getOperand(i)->getType()); +    int Slot = Table.getSlot(I->getOperand(i)->getType());      assert(Slot >= 0 && "No slot number for value!?!?");            output_vbr((unsigned)Slot, Out); - +          // Output arg ID itself      Slot = Table.getSlot(I->getOperand(i));      assert(Slot >= 0 && "No slot number for value!?!?");       @@ -214,13 +227,18 @@ void BytecodeWriter::processInstruction(const Instruction &I) {    if (Slot > MaxOpSlot) MaxOpSlot = Slot;    // Handle the special case for cast... -  if (isa<CastInst>(I) || isa<VarArgInst>(I)) { +  if (isa<CastInst>(I) || isa<VAArgInst>(I)) {      // Cast has to encode the destination type as the second argument in the      // packet, or else we won't know what type to cast to!      Slots[1] = Table.getSlot(I.getType());      assert(Slots[1] != -1 && "Cast return type unknown?");      if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1];      NumOperands++; +  } else if (const VANextInst *VANI = dyn_cast<VANextInst>(&I)) { +    Slots[1] = Table.getSlot(VANI->getArgType()); +    assert(Slots[1] != -1 && "va_next return type unknown?"); +    if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1]; +    NumOperands++;    } else if (const CallInst *CI = dyn_cast<CallInst>(&I)){// Handle VarArg calls      const PointerType *Ty = cast<PointerType>(CI->getCalledValue()->getType());      if (cast<FunctionType>(Ty->getElementType())->isVarArg()) {  | 
