summaryrefslogtreecommitdiff
path: root/include/llvm/CodeGen/MachineInstrAnnot.h
blob: b16408f9a36664c891e86468579a11b8c9396eb0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// $Id$ -*-c++-*-
//***************************************************************************
// File:
//	MachineInstrAnnot.h
// 
// Purpose:
//      Annotations used to pass information between code generation phases.
// 
// History:
//	5/10/02	 -  Vikram Adve  -  Created
//**************************************************************************/

#ifndef MACHINE_INSTR_ANNOT_h
#define MACHINE_INSTR_ANNOT_h

#include "llvm/Annotation.h"
#include "llvm/CodeGen/MachineInstr.h"
#include <vector>

class Value;
class TmpInstruction;
class CallInst;


class CallArgInfo {
private:
  // Flag values for different argument passing methods
  static const unsigned char IntArgReg = 0x1;
  static const unsigned char FPArgReg  = 0x2;
  static const unsigned char StackSlot = 0x4;
  
  const Value* argVal;                  // this argument
  const Value* argValCopy;              // second copy of arg. when multiple 
                                        // copies must be passed in registers
  unsigned char passingMethod;          // flags recording passing methods
  
public:
  // Constructors
  CallArgInfo(const Value* _argVal)
    : argVal(_argVal), argValCopy(NULL), passingMethod(0x0) {}
  
  CallArgInfo(const CallArgInfo& obj)
    : argVal(obj.argVal), argValCopy(obj.argValCopy),
      passingMethod(obj.passingMethod) {}
  
  // Accessor methods
  const Value*  getArgVal()       { return argVal; }
  const Value*  getArgCopy()      { return argValCopy; }
  bool          usesIntArgReg()   { return (bool) passingMethod & IntArgReg; } 
  bool          usesFPArgReg()    { return (bool) passingMethod & FPArgReg; } 
  bool          usesStackSlot()   { return (bool) passingMethod & StackSlot; } 
  
  // Modifier methods
  void          replaceArgVal(const Value* newVal) { argVal = newVal; }
  void          setUseIntArgReg() { passingMethod |= IntArgReg; }
  void          setUseFPArgReg()  { passingMethod |= FPArgReg; }
  void          setUseStackSlot() { passingMethod |= StackSlot; }
  void          setArgCopy(const Value* tmp) { argValCopy = tmp; }
};


class CallArgsDescriptor: public Annotation { // Annotation for a MachineInstr
private:
  static AnnotationID AID;              // AnnotationID for this class
  std::vector<CallArgInfo> argInfoVec;       // Descriptor for each argument
  const CallInst* callInstr;            // The call instruction == result value
  const Value* funcPtr;                 // Pointer for indirect calls 
  TmpInstruction* retAddrReg;           // Tmp value for return address reg.
  bool isVarArgs;                       // Is this a varargs call?
  bool noPrototype;                     // Is this a call with no prototype?
  
public:
  CallArgsDescriptor(const CallInst* _callInstr, TmpInstruction* _retAddrReg,
                     bool _isVarArgs, bool _noPrototype);
  
  // Accessor methods to retrieve information about the call
  // Note that operands are numbered 1..#CallArgs
  unsigned int    getNumArgs() const          { return argInfoVec.size(); }
  CallArgInfo&    getArgInfo(unsigned int op) { assert(op < argInfoVec.size());
                                                return argInfoVec[op]; }
  const CallInst* getReturnValue() const      { return callInstr; }
  const Value*    getIndirectFuncPtr() const  { return funcPtr; }
  TmpInstruction* getReturnAddrReg() const    { return retAddrReg; }
  bool            isVarArgsFunc() const       { return isVarArgs; }
  bool            hasNoPrototype() const      { return noPrototype; }
  
  // Annotation mechanism to annotate a MachineInstr with the descriptor.
  // This is not demand-driven because annotations can only be created
  // at restricted points during code generation.
  static inline CallArgsDescriptor *get(const MachineInstr* MI) {
    return (CallArgsDescriptor *) MI->getAnnotation(AID);
  }
};


#endif MACHINE_INSTR_ANNOT_h