Implement new helper methods for creating two-index GEP instructions
[oota-llvm.git] / lib / VMCore / iOperators.cpp
1 //===-- iOperators.cpp - Implement binary Operators ------------*- C++ -*--===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the nontrivial binary operator instructions.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/iOperators.h"
15 #include "llvm/Type.h"
16 #include "llvm/Constants.h"
17 #include "llvm/BasicBlock.h"
18 using namespace llvm;
19
20 //===----------------------------------------------------------------------===//
21 //                             BinaryOperator Class
22 //===----------------------------------------------------------------------===//
23
24 void BinaryOperator::init(BinaryOps iType, Value *S1, Value *S2)
25 {
26   Operands.reserve(2);
27   Operands.push_back(Use(S1, this));
28   Operands.push_back(Use(S2, this));
29   assert(S1 && S2 && S1->getType() == S2->getType());
30
31 #ifndef NDEBUG
32   switch (iType) {
33   case Add: case Sub:
34   case Mul: case Div:
35   case Rem:
36     assert(getType() == S1->getType() &&
37            "Arithmetic operation should return same type as operands!");
38     assert((getType()->isInteger() || getType()->isFloatingPoint()) && 
39            "Tried to create an arithmetic operation on a non-arithmetic type!");
40     break;
41   case And: case Or:
42   case Xor:
43     assert(getType() == S1->getType() &&
44            "Logical operation should return same type as operands!");
45     assert(getType()->isIntegral() &&
46            "Tried to create an logical operation on a non-integral type!");
47     break;
48   case SetLT: case SetGT: case SetLE:
49   case SetGE: case SetEQ: case SetNE:
50     assert(getType() == Type::BoolTy && "Setcc must return bool!");
51   default:
52     break;
53   }
54 #endif
55 }
56
57 BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2,
58                                        const std::string &Name,
59                                        Instruction *InsertBefore) {
60   assert(S1->getType() == S2->getType() &&
61          "Cannot create binary operator with two operands of differing type!");
62   switch (Op) {
63   // Binary comparison operators...
64   case SetLT: case SetGT: case SetLE:
65   case SetGE: case SetEQ: case SetNE:
66     return new SetCondInst(Op, S1, S2, Name, InsertBefore);
67
68   default:
69     return new BinaryOperator(Op, S1, S2, S1->getType(), Name, InsertBefore);
70   }
71 }
72
73 BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2,
74                                        const std::string &Name,
75                                        BasicBlock *InsertAtEnd) {
76   BinaryOperator *Res = create(Op, S1, S2, Name);
77   InsertAtEnd->getInstList().push_back(Res);
78   return Res;
79 }
80
81 BinaryOperator *BinaryOperator::createNeg(Value *Op, const std::string &Name,
82                                           Instruction *InsertBefore) {
83   if (!Op->getType()->isFloatingPoint())
84     return new BinaryOperator(Instruction::Sub,
85                               Constant::getNullValue(Op->getType()), Op,
86                               Op->getType(), Name, InsertBefore);
87   else
88     return new BinaryOperator(Instruction::Sub,
89                               ConstantFP::get(Op->getType(), -0.0), Op,
90                               Op->getType(), Name, InsertBefore);
91 }
92
93 BinaryOperator *BinaryOperator::createNeg(Value *Op, const std::string &Name,
94                                           BasicBlock *InsertAtEnd) {
95   if (!Op->getType()->isFloatingPoint())
96     return new BinaryOperator(Instruction::Sub,
97                               Constant::getNullValue(Op->getType()), Op,
98                               Op->getType(), Name, InsertAtEnd);
99   else
100     return new BinaryOperator(Instruction::Sub,
101                               ConstantFP::get(Op->getType(), -0.0), Op,
102                               Op->getType(), Name, InsertAtEnd);
103 }
104
105 BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name,
106                                           Instruction *InsertBefore) {
107   return new BinaryOperator(Instruction::Xor, Op,
108                             ConstantIntegral::getAllOnesValue(Op->getType()),
109                             Op->getType(), Name, InsertBefore);
110 }
111
112 BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name,
113                                           BasicBlock *InsertAtEnd) {
114   return new BinaryOperator(Instruction::Xor, Op,
115                             ConstantIntegral::getAllOnesValue(Op->getType()),
116                             Op->getType(), Name, InsertAtEnd);
117 }
118
119
120 // isConstantAllOnes - Helper function for several functions below
121 static inline bool isConstantAllOnes(const Value *V) {
122   return isa<ConstantIntegral>(V) &&cast<ConstantIntegral>(V)->isAllOnesValue();
123 }
124
125 bool BinaryOperator::isNeg(const Value *V) {
126   if (const BinaryOperator *Bop = dyn_cast<BinaryOperator>(V))
127     if (Bop->getOpcode() == Instruction::Sub)
128       if (!V->getType()->isFloatingPoint())
129         return Bop->getOperand(0) == Constant::getNullValue(Bop->getType());
130       else
131         return Bop->getOperand(0) == ConstantFP::get(Bop->getType(), -0.0);
132   return false;
133 }
134
135 bool BinaryOperator::isNot(const Value *V) {
136   if (const BinaryOperator *Bop = dyn_cast<BinaryOperator>(V))
137     return (Bop->getOpcode() == Instruction::Xor &&
138             (isConstantAllOnes(Bop->getOperand(1)) ||
139              isConstantAllOnes(Bop->getOperand(0))));
140   return false;
141 }
142
143 Value *BinaryOperator::getNegArgument(BinaryOperator *Bop) {
144   assert(isNeg(Bop) && "getNegArgument from non-'neg' instruction!");
145   return Bop->getOperand(1);
146 }
147
148 const Value *BinaryOperator::getNegArgument(const BinaryOperator *Bop) {
149   return getNegArgument((BinaryOperator*)Bop);
150 }
151
152 Value *BinaryOperator::getNotArgument(BinaryOperator *Bop) {
153   assert(isNot(Bop) && "getNotArgument on non-'not' instruction!");
154   Value *Op0 = Bop->getOperand(0);
155   Value *Op1 = Bop->getOperand(1);
156   if (isConstantAllOnes(Op0)) return Op1;
157
158   assert(isConstantAllOnes(Op1));
159   return Op0;
160 }
161
162 const Value *BinaryOperator::getNotArgument(const BinaryOperator *Bop) {
163   return getNotArgument((BinaryOperator*)Bop);
164 }
165
166
167 // swapOperands - Exchange the two operands to this instruction.  This
168 // instruction is safe to use on any binary instruction and does not
169 // modify the semantics of the instruction.  If the instruction is
170 // order dependent (SetLT f.e.) the opcode is changed.
171 //
172 bool BinaryOperator::swapOperands() {
173   if (isCommutative())
174     ;  // If the instruction is commutative, it is safe to swap the operands
175   else if (SetCondInst *SCI = dyn_cast<SetCondInst>(this))
176     /// FIXME: SetCC instructions shouldn't all have different opcodes.
177     setOpcode(SCI->getSwappedCondition());
178   else
179     return true;   // Can't commute operands
180
181   std::swap(Operands[0], Operands[1]);
182   return false;
183 }
184
185
186 //===----------------------------------------------------------------------===//
187 //                             SetCondInst Class
188 //===----------------------------------------------------------------------===//
189
190 SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2, 
191                          const std::string &Name, Instruction *InsertBefore)
192   : BinaryOperator(Opcode, S1, S2, Type::BoolTy, Name, InsertBefore) {
193
194   // Make sure it's a valid type... getInverseCondition will assert out if not.
195   assert(getInverseCondition(Opcode));
196 }
197
198 SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2, 
199                          const std::string &Name, BasicBlock *InsertAtEnd)
200   : BinaryOperator(Opcode, S1, S2, Type::BoolTy, Name, InsertAtEnd) {
201
202   // Make sure it's a valid type... getInverseCondition will assert out if not.
203   assert(getInverseCondition(Opcode));
204 }
205
206 // getInverseCondition - Return the inverse of the current condition opcode.
207 // For example seteq -> setne, setgt -> setle, setlt -> setge, etc...
208 //
209 Instruction::BinaryOps SetCondInst::getInverseCondition(BinaryOps Opcode) {
210   switch (Opcode) {
211   default:
212     assert(0 && "Unknown setcc opcode!");
213   case SetEQ: return SetNE;
214   case SetNE: return SetEQ;
215   case SetGT: return SetLE;
216   case SetLT: return SetGE;
217   case SetGE: return SetLT;
218   case SetLE: return SetGT;
219   }
220 }
221
222 // getSwappedCondition - Return the condition opcode that would be the result
223 // of exchanging the two operands of the setcc instruction without changing
224 // the result produced.  Thus, seteq->seteq, setle->setge, setlt->setgt, etc.
225 //
226 Instruction::BinaryOps SetCondInst::getSwappedCondition(BinaryOps Opcode) {
227   switch (Opcode) {
228   default: assert(0 && "Unknown setcc instruction!");
229   case SetEQ: case SetNE: return Opcode;
230   case SetGT: return SetLT;
231   case SetLT: return SetGT;
232   case SetGE: return SetLE;
233   case SetLE: return SetGE;
234   }
235 }