llvm.org GIT mirror llvm / 00b1688
Eliminate all remaining tabs and trailing spaces. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22523 91177308-0d34-0410-b5e6-96231b3b80d8 Jeff Cohen 14 years ago
69 changed file(s) with 1283 addition(s) and 1283 deletion(s). Raw diff Collapse all Expand all
88 //
99 // Parallel JIT
1010 //
11 // This test program creates two LLVM functions then calls them from three
11 // This test program creates two LLVM functions then calls them from three
1212 // separate threads. It requires the pthreads library.
1313 // The three threads are created and then block waiting on a condition variable.
1414 // Once all threads are blocked on the conditional variable, the main thread
2727 #include
2828 using namespace llvm;
2929
30 static Function* createAdd1( Module* M )
30 static Function* createAdd1(Module* M)
3131 {
3232 // Create the add1 function entry and insert this entry into module M. The
3333 // function will have a return type of "int" and take an argument of "int".
3434 // The '0' terminates the list of argument types.
3535 Function *Add1F = M->getOrInsertFunction("add1", Type::IntTy, Type::IntTy, 0);
36
36
3737 // Add a basic block to the function. As before, it automatically inserts
3838 // because of the last argument.
3939 BasicBlock *BB = new BasicBlock("EntryBlock", Add1F);
40
40
4141 // Get pointers to the constant `1'.
4242 Value *One = ConstantSInt::get(Type::IntTy, 1);
43
43
4444 // Get pointers to the integer argument of the add1 function...
4545 assert(Add1F->arg_begin() != Add1F->arg_end()); // Make sure there's an arg
4646 Argument *ArgX = Add1F->arg_begin(); // Get the arg
4747 ArgX->setName("AnArg"); // Give it a nice symbolic name for fun.
48
48
4949 // Create the add instruction, inserting it into the end of BB.
5050 Instruction *Add = BinaryOperator::createAdd(One, ArgX, "addresult", BB);
51
51
5252 // Create the return instruction and add it to the basic block
5353 new ReturnInst(Add, BB);
54
55 // Now, function add1 is ready.
54
55 // Now, function add1 is ready.
5656 return Add1F;
5757 }
5858
6161 // Create the fib function and insert it into module M. This function is said
6262 // to return an int and take an int parameter.
6363 Function *FibF = M->getOrInsertFunction("fib", Type::IntTy, Type::IntTy, 0);
64
64
6565 // Add a basic block to the function.
6666 BasicBlock *BB = new BasicBlock("EntryBlock", FibF);
67
67
6868 // Get pointers to the constants.
6969 Value *One = ConstantSInt::get(Type::IntTy, 1);
7070 Value *Two = ConstantSInt::get(Type::IntTy, 2);
71
71
7272 // Get pointer to the integer argument of the add1 function...
7373 Argument *ArgX = FibF->arg_begin(); // Get the arg.
7474 ArgX->setName("AnArg"); // Give it a nice symbolic name for fun.
75
75
7676 // Create the true_block.
7777 BasicBlock *RetBB = new BasicBlock("return", FibF);
7878 // Create an exit block.
7979 BasicBlock* RecurseBB = new BasicBlock("recurse", FibF);
80
80
8181 // Create the "if (arg < 2) goto exitbb"
8282 Value *CondInst = BinaryOperator::createSetLE(ArgX, Two, "cond", BB);
8383 new BranchInst(RetBB, RecurseBB, CondInst, BB);
84
84
8585 // Create: ret int 1
8686 new ReturnInst(One, RetBB);
87
87
8888 // create fib(x-1)
8989 Value *Sub = BinaryOperator::createSub(ArgX, One, "arg", RecurseBB);
9090 Value *CallFibX1 = new CallInst(FibF, Sub, "fibx1", RecurseBB);
91
91
9292 // create fib(x-2)
9393 Sub = BinaryOperator::createSub(ArgX, Two, "arg", RecurseBB);
9494 Value *CallFibX2 = new CallInst(FibF, Sub, "fibx2", RecurseBB);
95
95
9696 // fib(x-1)+fib(x-2)
97 Value *Sum =
97 Value *Sum =
9898 BinaryOperator::createAdd(CallFibX1, CallFibX2, "addresult", RecurseBB);
99
99
100100 // Create the return instruction and add it to the basic block
101101 new ReturnInst(Sum, RecurseBB);
102
102
103103 return FibF;
104104 }
105105
119119 {
120120 n = 0;
121121 waitFor = 0;
122
122
123123 int result = pthread_cond_init( &condition, NULL );
124124 assert( result == 0 );
125
125
126126 result = pthread_mutex_init( &mutex, NULL );
127127 assert( result == 0 );
128128 }
129
129
130130 ~WaitForThreads()
131131 {
132132 int result = pthread_cond_destroy( &condition );
133133 assert( result == 0 );
134
134
135135 result = pthread_mutex_destroy( &mutex );
136136 assert( result == 0 );
137137 }
138
138
139139 // All threads will stop here until another thread calls releaseThreads
140140 void block()
141141 {
143143 assert( result == 0 );
144144 n ++;
145145 //~ std::cout << "block() n " << n << " waitFor " << waitFor << std::endl;
146
146
147147 assert( waitFor == 0 || n <= waitFor );
148 if ( waitFor > 0 && n == waitFor )
148 if ( waitFor > 0 && n == waitFor )
149149 {
150150 // There are enough threads blocked that we can release all of them
151151 std::cout << "Unblocking threads from block()" << std::endl;
152152 unblockThreads();
153 }
154 else
153 }
154 else
155155 {
156156 // We just need to wait until someone unblocks us
157157 result = pthread_cond_wait( &condition, &mutex );
158158 assert( result == 0 );
159159 }
160
160
161161 // unlock the mutex before returning
162162 result = pthread_mutex_unlock( &mutex );
163163 assert( result == 0 );
164164 }
165
165
166166 // If there are num or more threads blocked, it will signal them all
167167 // Otherwise, this thread blocks until there are enough OTHER threads
168168 // blocked
170170 {
171171 int result = pthread_mutex_lock( &mutex );
172172 assert( result == 0 );
173
173
174174 if ( n >= num ) {
175175 std::cout << "Unblocking threads from releaseThreads()" << std::endl;
176176 unblockThreads();
177 }
178 else
177 }
178 else
179179 {
180180 waitFor = num;
181181 pthread_cond_wait( &condition, &mutex );
182182 }
183
183
184184 // unlock the mutex before returning
185185 result = pthread_mutex_unlock( &mutex );
186186 assert( result == 0 );
187187 }
188
188
189189 private:
190190 void unblockThreads()
191191 {
193193 // enter while threads are exiting, they will block instead
194194 // of triggering a new release of threads
195195 n = 0;
196
196
197197 // Reset waitFor to zero: this way, if waitFor threads enter
198198 // while threads are exiting, they will block instead of
199199 // triggering a new release of threads
202202 int result = pthread_cond_broadcast( &condition );
203203 assert( result == 0 );
204204 }
205
205
206206 size_t n;
207207 size_t waitFor;
208208 pthread_cond_t condition;
214214 void* callFunc( void* param )
215215 {
216216 struct threadParams* p = (struct threadParams*) param;
217
217
218218 // Call the `foo' function with no arguments:
219219 std::vector Args(1);
220220 Args[0].IntVal = p->value;
221
221
222222 synchronize.block(); // wait until other threads are at this point
223223 GenericValue gv = p->EE->runFunction(p->F, Args);
224
224
225225 return (void*) intptr_t(gv.IntVal);
226226 }
227227
228 int main()
228 int main()
229229 {
230230 // Create some module to put our function into it.
231231 Module *M = new Module("test");
232
232
233233 Function* add1F = createAdd1( M );
234234 Function* fibF = CreateFibFunction( M );
235
235
236236 // Now we create the JIT.
237237 ExistingModuleProvider* MP = new ExistingModuleProvider(M);
238238 ExecutionEngine* EE = ExecutionEngine::create(MP, false);
239
239
240240 //~ std::cout << "We just constructed this LLVM module:\n\n" << *M;
241241 //~ std::cout << "\n\nRunning foo: " << std::flush;
242
242
243243 // Create one thread for add1 and two threads for fib
244244 struct threadParams add1 = { EE, add1F, 1000 };
245245 struct threadParams fib1 = { EE, fibF, 39 };
246246 struct threadParams fib2 = { EE, fibF, 42 };
247
247
248248 pthread_t add1Thread;
249249 int result = pthread_create( &add1Thread, NULL, callFunc, &add1 );
250250 if ( result != 0 ) {
251251 std::cerr << "Could not create thread" << std::endl;
252252 return 1;
253253 }
254
254
255255 pthread_t fibThread1;
256256 result = pthread_create( &fibThread1, NULL, callFunc, &fib1 );
257257 if ( result != 0 ) {
258258 std::cerr << "Could not create thread" << std::endl;
259259 return 1;
260260 }
261
261
262262 pthread_t fibThread2;
263263 result = pthread_create( &fibThread2, NULL, callFunc, &fib2 );
264264 if ( result != 0 ) {
265265 std::cerr << "Could not create thread" << std::endl;
266266 return 1;
267267 }
268
268
269269 synchronize.releaseThreads(3); // wait until other threads are at this point
270
270
271271 void* returnValue;
272272 result = pthread_join( add1Thread, &returnValue );
273273 if ( result != 0 ) {
275275 return 1;
276276 }
277277 std::cout << "Add1 returned " << intptr_t(returnValue) << std::endl;
278
278
279279 result = pthread_join( fibThread1, &returnValue );
280280 if ( result != 0 ) {
281281 std::cerr << "Could not join thread" << std::endl;
282282 return 1;
283283 }
284284 std::cout << "Fib1 returned " << intptr_t(returnValue) << std::endl;
285
285
286286 result = pthread_join( fibThread2, &returnValue );
287287 if ( result != 0 ) {
288288 std::cerr << "Could not join thread" << std::endl;
289289 return 1;
290290 }
291291 std::cout << "Fib2 returned " << intptr_t(returnValue) << std::endl;
292
292
293293 return 0;
294294 }
417417 DSG->getReturnNodes().insert(std::make_pair(F, DSNodeHandle()));
418418
419419 if (F->getName() == "free") { // Taking the address of free.
420
420
421421 // Free should take a single pointer argument, mark it as heap memory.
422422 DSNode *N = new DSNode(0, DSG);
423423 N->setHeapNodeMarker();
681681 const Type* ArgTy = getValue(iType, Oprnds[0])->getType();
682682 Function* NF = TheModule->getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0);
683683
684 //b = vaarg a, t ->
684 //b = vaarg a, t ->
685685 //foo = alloca 1 of t
686 //bar = vacopy a
686 //bar = vacopy a
687687 //store bar -> foo
688688 //b = vaarg foo, t
689689 AllocaInst* foo = new AllocaInst(ArgTy, 0, "vaarg.fix");
169169
170170 if(Function* F = M->getNamedFunction("llvm.va_start")) {
171171 assert(F->arg_size() == 0 && "Obsolete va_start takes 0 argument!");
172
172
173173 //foo = va_start()
174174 // ->
175175 //bar = alloca typeof(foo)
176176 //va_start(bar)
177177 //foo = load bar
178
178
179179 const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
180180 const Type* ArgTy = F->getFunctionType()->getReturnType();
181181 const Type* ArgTyPtr = PointerType::get(ArgTy);
182 Function* NF = M->getOrInsertFunction("llvm.va_start",
182 Function* NF = M->getOrInsertFunction("llvm.va_start",
183183 RetTy, ArgTyPtr, 0);
184184
185185 for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;)
192192 }
193193 F->setName("");
194194 }
195
195
196196 if(Function* F = M->getNamedFunction("llvm.va_end")) {
197197 assert(F->arg_size() == 1 && "Obsolete va_end takes 1 argument!");
198198 //vaend foo
202202 const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
203203 const Type* ArgTy = F->getFunctionType()->getParamType(0);
204204 const Type* ArgTyPtr = PointerType::get(ArgTy);
205 Function* NF = M->getOrInsertFunction("llvm.va_end",
205 Function* NF = M->getOrInsertFunction("llvm.va_end",
206206 RetTy, ArgTyPtr, 0);
207
207
208208 for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;)
209209 if (CallInst* CI = dyn_cast(*I++)) {
210210 AllocaInst* bar = new AllocaInst(ArgTy, 0, "vaend.fix.1", CI);
214214 }
215215 F->setName("");
216216 }
217
217
218218 if(Function* F = M->getNamedFunction("llvm.va_copy")) {
219219 assert(F->arg_size() == 1 && "Obsolete va_copy takes 1 argument!");
220220 //foo = vacopy(bar)
224224 //store bar -> b
225225 //vacopy(a, b)
226226 //foo = load a
227
227
228228 const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
229229 const Type* ArgTy = F->getFunctionType()->getReturnType();
230230 const Type* ArgTyPtr = PointerType::get(ArgTy);
231 Function* NF = M->getOrInsertFunction("llvm.va_copy",
231 Function* NF = M->getOrInsertFunction("llvm.va_copy",
232232 RetTy, ArgTyPtr, ArgTyPtr, 0);
233
233
234234 for(Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E;)
235235 if (CallInst* CI = dyn_cast(*I++)) {
236236 AllocaInst* a = new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI);
627627 Opcode = 57; // FastCC invoke.
628628 else if (II->getCallingConv() != CallingConv::C)
629629 Opcode = 56; // Invoke escape sequence.
630
630
631631 } else if (isa(I) && cast(I).isVolatile()) {
632632 Opcode = 62;
633633 } else if (isa(I) && cast(I).isVolatile()) {
107107 ELFWriter::ELFSection::SHF_EXECINSTR |
108108 ELFWriter::ELFSection::SHF_ALLOC);
109109 OutBuffer = &ES->SectionData;
110
110
111111 // Upgrade the section alignment if required.
112112 if (ES->Align < Align) ES->Align = Align;
113
113
114114 // Add padding zeros to the end of the buffer to make sure that the
115115 // function will start on the correct byte alignment within the section.
116116 size_t SectionOff = OutBuffer->size();
117117 ELFWriter::align(*OutBuffer, Align);
118
118
119119 FnStart = OutBuffer->size();
120120 }
121121
124124 void ELFCodeEmitter::finishFunction(MachineFunction &F) {
125125 // We now know the size of the function, add a symbol to represent it.
126126 ELFWriter::ELFSym FnSym(F.getFunction());
127
127
128128 // Figure out the binding (linkage) of the symbol.
129129 switch (F.getFunction()->getLinkage()) {
130130 default:
148148 FnSym.SectionIdx = ES->SectionIdx;
149149 FnSym.Value = FnStart; // Value = Offset from start of Section.
150150 FnSym.Size = OutBuffer->size()-FnStart;
151
151
152152 // Finally, add it to the symtab.
153153 EW.SymbolTable.push_back(FnSym);
154154 }
161161 e_machine = 0; // e_machine defaults to 'No Machine'
162162 e_flags = 0; // e_flags defaults to 0, no flags.
163163
164 is64Bit = TM.getTargetData().getPointerSizeInBits() == 64;
164 is64Bit = TM.getTargetData().getPointerSizeInBits() == 64;
165165 isLittleEndian = TM.getTargetData().isLittleEndian();
166166
167167 // Create the machine code emitter object for this target.
180180
181181 // Local alias to shortenify coming code.
182182 std::vector &FH = FileHeader;
183
183
184184 outbyte(FH, 0x7F); // EI_MAG0
185185 outbyte(FH, 'E'); // EI_MAG1
186186 outbyte(FH, 'L'); // EI_MAG2
189189 outbyte(FH, isLittleEndian ? 1 : 2); // EI_DATA
190190 outbyte(FH, 1); // EI_VERSION
191191 FH.resize(16); // EI_PAD up to 16 bytes.
192
192
193193 // This should change for shared objects.
194194 outhalf(FH, 1); // e_type = ET_REL
195195 outhalf(FH, e_machine); // e_machine = whatever the target wants
206206 outhalf(FH, 0); // e_phnum = # prog header entries = 0
207207 outhalf(FH, is64Bit ? 64 : 40); // e_shentsize = sect hdr entry size
208208
209
209
210210 ELFHeader_e_shnum_Offset = FH.size();
211211 outhalf(FH, 0); // e_shnum = # of section header ents
212212 ELFHeader_e_shstrndx_Offset = FH.size();
234234 SymbolTable.push_back(ExternalSym);
235235 return;
236236 }
237
237
238238 const Type *GVType = (const Type*)GV->getType();
239239 unsigned Align = TM.getTargetData().getTypeAlignment(GVType);
240240 unsigned Size = TM.getTargetData().getTypeSize(GVType);
472472 // Now that we know where all of the sections will be emitted, set the e_shnum
473473 // entry in the ELF header.
474474 fixhalf(FileHeader, NumSections, ELFHeader_e_shnum_Offset);
475
475
476476 // Now that we know the offset in the file of the section table, update the
477477 // e_shoff address in the ELF header.
478478 fixaddr(FileHeader, FileOff, ELFHeader_e_shoff_Offset);
479
479
480480 // Now that we know all of the data in the file header, emit it and all of the
481481 // sections!
482482 O.write((char*)&FileHeader[0], FileHeader.size());
515515 for (size_t NewFileOff = (FileOff+TableAlign-1) & ~(TableAlign-1);
516516 FileOff != NewFileOff; ++FileOff)
517517 O.put(0xAB);
518
518
519519 // Emit the section table itself.
520520 O.write((char*)&Table[0], Table.size());
521521 }
149149 ConstantExpr::getCast(ConstantUInt::get(Type::ULongTy,
150150 MaskValues[ct]), V->getType());
151151 Value *LHS = BinaryOperator::createAnd(V, MaskCst, "cppop.and1", IP);
152 Value *VShift = new ShiftInst(Instruction::Shr, V,
152 Value *VShift = new ShiftInst(Instruction::Shr, V,
153153 ConstantInt::get(Type::UByteTy, i), "ctpop.sh", IP);
154154 Value *RHS = BinaryOperator::createAnd(VShift, MaskCst, "cppop.and2", IP);
155155 V = BinaryOperator::createAdd(LHS, RHS, "ctpop.step", IP);
127127 SDOperand ExpandLegalUINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT);
128128 SDOperand PromoteLegalINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT,
129129 bool isSigned);
130
130
131131 bool ExpandShift(unsigned Opc, SDOperand Op, SDOperand Amt,
132132 SDOperand &Lo, SDOperand &Hi);
133133 void ExpandShiftParts(unsigned NodeOp, SDOperand Op, SDOperand Amt,
151151 "Too many value types for ValueTypeActions to hold!");
152152 }
153153
154 /// ExpandLegalUINT_TO_FP - This function is responsible for legalizing a
154 /// ExpandLegalUINT_TO_FP - This function is responsible for legalizing a
155155 /// UINT_TO_FP operation of the specified operand when the target requests that
156156 /// we expand it. At this point, we know that the result and operand types are
157157 /// legal for the target.
158158 SDOperand SelectionDAGLegalize::ExpandLegalUINT_TO_FP(SDOperand Op0,
159159 MVT::ValueType DestVT) {
160160 SDOperand Tmp1 = DAG.getNode(ISD::SINT_TO_FP, DestVT, Op0);
161
162 SDOperand SignSet = DAG.getSetCC(ISD::SETLT, TLI.getSetCCResultTy(),
161
162 SDOperand SignSet = DAG.getSetCC(ISD::SETLT, TLI.getSetCCResultTy(),
163163 Op0,
164 DAG.getConstant(0,
164 DAG.getConstant(0,
165165 Op0.getValueType()));
166166 SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4);
167167 SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
168168 SignSet, Four, Zero);
169
169
170170 // If the sign bit of the integer is set, the large number will be treated as
171171 // a negative number. To counteract this, the dynamic code adds an offset
172172 // depending on the data type.
180180 }
181181 if (TLI.isLittleEndian()) FF <<= 32;
182182 static Constant *FudgeFactor = ConstantUInt::get(Type::ULongTy, FF);
183
183
184184 MachineConstantPool *CP = DAG.getMachineFunction().getConstantPool();
185185 SDOperand CPIdx = DAG.getConstantPool(CP->getConstantPoolIndex(FudgeFactor),
186186 TLI.getPointerTy());
195195 DAG.getEntryNode(), CPIdx,
196196 DAG.getSrcValue(NULL), MVT::f32));
197197 }
198
198
199199 NeedsAnotherIteration = true;
200200 return DAG.getNode(ISD::ADD, DestVT, Tmp1, FudgeInReg);
201201 }
202202
203 /// PromoteLegalUINT_TO_FP - This function is responsible for legalizing a
203 /// PromoteLegalUINT_TO_FP - This function is responsible for legalizing a
204204 /// UINT_TO_FP operation of the specified operand when the target requests that
205205 /// we promote it. At this point, we know that the result and operand types are
206206 /// legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP
210210 bool isSigned) {
211211 // First step, figure out the appropriate *INT_TO_FP operation to use.
212212 MVT::ValueType NewInTy = LegalOp.getValueType();
213
213
214214 unsigned OpToUse = 0;
215
215
216216 // Scan for the appropriate larger type to use.
217217 while (1) {
218218 NewInTy = (MVT::ValueType)(NewInTy+1);
219219 assert(MVT::isInteger(NewInTy) && "Ran out of possibilities!");
220
220
221221 // If the target supports SINT_TO_FP of this type, use it.
222222 switch (TLI.getOperationAction(ISD::SINT_TO_FP, NewInTy)) {
223223 default: break;
231231 }
232232 if (OpToUse) break;
233233 if (isSigned) continue;
234
234
235235 // If the target supports UINT_TO_FP of this type, use it.
236236 switch (TLI.getOperationAction(ISD::UINT_TO_FP, NewInTy)) {
237237 default: break;
244244 break;
245245 }
246246 if (OpToUse) break;
247
247
248248 // Otherwise, try a larger type.
249249 }
250250
251251 // Make sure to legalize any nodes we create here in the next pass.
252252 NeedsAnotherIteration = true;
253
253
254254 // Okay, we found the operation and type to use. Zero extend our input to the
255255 // desired type then run the operation on it.
256256 return DAG.getNode(OpToUse, DestVT,
759759 float F;
760760 } V;
761761 V.F = CFP->getValue();
762 Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1,
762 Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1,
763763 DAG.getConstant(V.I, MVT::i32), Tmp2,
764764 Node->getOperand(3));
765765 } else {
769769 double F;
770770 } V;
771771 V.F = CFP->getValue();
772 Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1,
772 Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1,
773773 DAG.getConstant(V.I, MVT::i64), Tmp2,
774774 Node->getOperand(3));
775775 }
12811281 break;
12821282 case ISD::CTTZ:
12831283 //if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT)
1284 Tmp2 = DAG.getSetCC(ISD::SETEQ, TLI.getSetCCResultTy(), Tmp1,
1284 Tmp2 = DAG.getSetCC(ISD::SETEQ, TLI.getSetCCResultTy(), Tmp1,
12851285 DAG.getConstant(getSizeInBits(NVT), NVT));
1286 Result = DAG.getNode(ISD::SELECT, NVT, Tmp2,
1286 Result = DAG.getNode(ISD::SELECT, NVT, Tmp2,
12871287 DAG.getConstant(getSizeInBits(OVT),NVT), Tmp1);
12881288 break;
12891289 case ISD::CTLZ:
12901290 //Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT))
1291 Result = DAG.getNode(ISD::SUB, NVT, Tmp1,
1292 DAG.getConstant(getSizeInBits(NVT) -
1291 Result = DAG.getNode(ISD::SUB, NVT, Tmp1,
1292 DAG.getConstant(getSizeInBits(NVT) -
12931293 getSizeInBits(OVT), NVT));
12941294 break;
12951295 }
13131313 //x = (x & mask[i][len/8]) + (x >> (1 << i) & mask[i][len/8])
13141314 Tmp2 = DAG.getConstant(mask[i], VT);
13151315 Tmp3 = DAG.getConstant(1ULL << i, ShVT);
1316 Tmp1 = DAG.getNode(ISD::ADD, VT,
1316 Tmp1 = DAG.getNode(ISD::ADD, VT,
13171317 DAG.getNode(ISD::AND, VT, Tmp1, Tmp2),
13181318 DAG.getNode(ISD::AND, VT,
13191319 DAG.getNode(ISD::SRL, VT, Tmp1, Tmp3),
13281328 x = x | (x >> 2);
13291329 ...
13301330 x = x | (x >>16);
1331 x = x | (x >>32); // for 64-bit input
1331 x = x | (x >>32); // for 64-bit input
13321332 return popcount(~x);
1333
1333
13341334 but see also: http://www.hackersdelight.org/HDcode/nlz.cc */
13351335 MVT::ValueType VT = Tmp1.getValueType();
13361336 MVT::ValueType ShVT = TLI.getShiftAmountTy();
13371337 unsigned len = getSizeInBits(VT);
13381338 for (unsigned i = 0; (1U << i) <= (len / 2); ++i) {
13391339 Tmp3 = DAG.getConstant(1ULL << i, ShVT);
1340 Tmp1 = DAG.getNode(ISD::OR, VT, Tmp1,
1340 Tmp1 = DAG.getNode(ISD::OR, VT, Tmp1,
13411341 DAG.getNode(ISD::SRL, VT, Tmp1, Tmp3));
13421342 }
13431343 Tmp3 = DAG.getNode(ISD::XOR, VT, Tmp1, DAG.getConstant(~0ULL, VT));
13451345 break;
13461346 }
13471347 case ISD::CTTZ: {
1348 // for now, we use: { return popcount(~x & (x - 1)); }
1348 // for now, we use: { return popcount(~x & (x - 1)); }
13491349 // unless the target has ctlz but not ctpop, in which case we use:
13501350 // { return 32 - nlz(~x & (x-1)); }
13511351 // see also http://www.hackersdelight.org/HDcode/ntz.cc
13521352 MVT::ValueType VT = Tmp1.getValueType();
13531353 Tmp2 = DAG.getConstant(~0ULL, VT);
1354 Tmp3 = DAG.getNode(ISD::AND, VT,
1354 Tmp3 = DAG.getNode(ISD::AND, VT,
13551355 DAG.getNode(ISD::XOR, VT, Tmp1, Tmp2),
13561356 DAG.getNode(ISD::SUB, VT, Tmp1,
13571357 DAG.getConstant(1, VT)));
13581358 // If ISD::CTLZ is legal and CTPOP isn't, then do that instead
13591359 if (TLI.getOperationAction(ISD::CTPOP, VT) != TargetLowering::Legal &&
13601360 TLI.getOperationAction(ISD::CTLZ, VT) == TargetLowering::Legal) {
1361 Result = LegalizeOp(DAG.getNode(ISD::SUB, VT,
1361 Result = LegalizeOp(DAG.getNode(ISD::SUB, VT,
13621362 DAG.getConstant(getSizeInBits(VT), VT),
13631363 DAG.getNode(ISD::CTLZ, VT, Tmp3)));
13641364 } else {
13731373 break;
13741374 }
13751375 break;
1376
1376
13771377 // Unary operators
13781378 case ISD::FABS:
13791379 case ISD::FNEG:
14521452 if (Node->getOpcode() == ISD::UINT_TO_FP ||
14531453 Node->getOpcode() == ISD::SINT_TO_FP) {
14541454 bool isSigned = Node->getOpcode() == ISD::SINT_TO_FP;
1455 switch (TLI.getOperationAction(Node->getOpcode(),
1455 switch (TLI.getOperationAction(Node->getOpcode(),
14561456 Node->getOperand(0).getValueType())) {
14571457 default: assert(0 && "Unknown operation action!");
14581458 case TargetLowering::Expand:
19351935 break;
19361936 case ISD::CTTZ:
19371937 //if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT)
1938 Tmp2 = DAG.getSetCC(ISD::SETEQ, MVT::i1, Tmp1,
1938 Tmp2 = DAG.getSetCC(ISD::SETEQ, MVT::i1, Tmp1,
19391939 DAG.getConstant(getSizeInBits(NVT), NVT));
1940 Result = DAG.getNode(ISD::SELECT, NVT, Tmp2,
1940 Result = DAG.getNode(ISD::SELECT, NVT, Tmp2,
19411941 DAG.getConstant(getSizeInBits(VT),NVT), Tmp1);
19421942 break;
19431943 case ISD::CTLZ:
19441944 //Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT))
1945 Result = DAG.getNode(ISD::SUB, NVT, Tmp1,
1946 DAG.getConstant(getSizeInBits(NVT) -
1945 Result = DAG.getNode(ISD::SUB, NVT, Tmp1,
1946 DAG.getConstant(getSizeInBits(NVT) -
19471947 getSizeInBits(VT), NVT));
19481948 break;
19491949 }
22812281 return SDOperand(LatestCallSeqEnd, 0);
22822282 }
22832283
2284 /// SpliceCallInto - Given the result chain of a libcall (CallResult), and a
2284 /// SpliceCallInto - Given the result chain of a libcall (CallResult), and a
22852285 void SelectionDAGLegalize::SpliceCallInto(const SDOperand &CallResult,
22862286 SDNode *OutChain) {
22872287 // Nothing to splice it into?
25572557 unsigned IncrementSize = MVT::getSizeInBits(Lo.getValueType())/8;
25582558 Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
25592559 getIntPtrConstant(IncrementSize));
2560 //Is this safe? declaring that the two parts of the split load
2560 //Is this safe? declaring that the two parts of the split load
25612561 //are from the same instruction?
25622562 Hi = DAG.getLoad(NVT, Ch, Ptr, Node->getOperand(2));
25632563
12111211 break;
12121212 case ISD::SUB:
12131213 if (N1.getOpcode() == ISD::ADD) {
1214 if (N1.Val->getOperand(0) == N2 &&
1214 if (N1.Val->getOperand(0) == N2 &&
12151215 !MVT::isFloatingPoint(N2.getValueType()))
12161216 return N1.Val->getOperand(1); // (A+B)-A == B
12171217 if (N1.Val->getOperand(1) == N2 &&
12321232 if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG)
12331233 if (cast(N1.getOperand(1))->getVT() <= EVT)
12341234 return N1;
1235
1235
12361236 // If we are sign extending a sextload, return just the load.
12371237 if (N1.getOpcode() == ISD::SEXTLOAD)
12381238 if (cast(N1.getOperand(3))->getVT() <= EVT)
13101310
13111311
13121312 SDOperand SelectionDAG::getLoad(MVT::ValueType VT,
1313 SDOperand Chain, SDOperand Ptr,
1313 SDOperand Chain, SDOperand Ptr,
13141314 SDOperand SV) {
13151315 SDNode *&N = Loads[std::make_pair(Ptr, std::make_pair(Chain, VT))];
13161316 if (N) return SDOperand(N, 0);
14561456 }
14571457
14581458 SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
1459 SDOperand N1, SDOperand N2, SDOperand N3,
1459 SDOperand N1, SDOperand N2, SDOperand N3,
14601460 SDOperand N4) {
14611461 std::vector Ops;
14621462 Ops.reserve(4);
715715 Ops.push_back(getValue(I.getOperand(1)));
716716 Tmp = DAG.getNode(F->getIntrinsicID() == Intrinsic::readport ?
717717 ISD::READPORT : ISD::READIO, VTs, Ops);
718
718
719719 setValue(&I, Tmp);
720720 DAG.setRoot(Tmp.getValue(1));
721721 return;
886886 }
887887
888888 void SelectionDAGLowering::visitVAEnd(CallInst &I) {
889 DAG.setRoot(TLI.LowerVAEnd(getRoot(), getValue(I.getOperand(1)),
889 DAG.setRoot(TLI.LowerVAEnd(getRoot(), getValue(I.getOperand(1)),
890890 I.getOperand(1), DAG));
891891 }
892892
7676
7777 /// run - Start execution with the specified function and arguments.
7878 ///
79 GenericValue
79 GenericValue
8080 Interpreter::runFunction(Function *F,
8181 const std::vector &ArgValues) {
8282 assert (F && "Function *F was null at entry to run()");
217217 void JIT::runJITOnFunction(Function *F) {
218218 static bool isAlreadyCodeGenerating = false;
219219 assert(!isAlreadyCodeGenerating && "Error: Recursive compilation detected!");
220
220
221221 MutexGuard locked(lock);
222222
223223 // JIT the function
146146 /// StubToFunctionMap - Keep track of the function that each stub
147147 /// corresponds to.
148148 std::map StubToFunctionMap;
149
149
150150 public:
151151 std::map& getFunctionToStubMap(const MutexGuard& locked) {
152152 assert(locked.holds(TheJIT->lock));
153153 return FunctionToStubMap;
154154 }
155
155
156156 std::map& getStubToFunctionMap(const MutexGuard& locked) {
157157 assert(locked.holds(TheJIT->lock));
158158 return StubToFunctionMap;
159159 }
160160 };
161
161
162162 /// JITResolver - Keep track of, and resolve, call sites for functions that
163163 /// have not yet been compiled.
164164 class JITResolver {
339339
340340 public:
341341 JITEmitter(JIT &jit)
342 :MemMgr(jit.getJITInfo().needsGOT()),
342 :MemMgr(jit.getJITInfo().needsGOT()),
343343 nextGOTIndex(0)
344344 {
345 TheJIT = &jit;
346 DEBUG(std::cerr <<
347 (MemMgr.isManagingGOT() ? "JIT is managing GOT\n"
345 TheJIT = &jit;
346 DEBUG(std::cerr <<
347 (MemMgr.isManagingGOT() ? "JIT is managing GOT\n"
348348 : "JIT is not managing GOT\n"));
349349 }
350350
430430 // If the target REALLY wants a stub for this function, emit it now.
431431 if (!MR.doesntNeedFunctionStub())
432432 ResultPtr = getJITResolver(this).getExternalFunctionStub(ResultPtr);
433 } else if (MR.isGlobalValue())
433 } else if (MR.isGlobalValue())
434434 ResultPtr = getPointerToGlobal(MR.getGlobalValue(),
435435 CurBlock+MR.getMachineCodeOffset(),
436436 MR.doesntNeedFunctionStub());
437437 else //ConstantPoolIndex
438 ResultPtr =
438 ResultPtr =
439439 (void*)(intptr_t)getConstantPoolEntryAddress(MR.getConstantPoolIndex());
440
440
441441 MR.setResultPointer(ResultPtr);
442442
443443 // if we are managing the got, check to see if this pointer has all ready
407407
408408 // Decompress it
409409 int bzerr = BZ_OK;
410 while ( BZ_OK == (bzerr = BZ2_bzDecompress(&bzdata)) &&
410 while ( BZ_OK == (bzerr = BZ2_bzDecompress(&bzdata)) &&
411411 bzdata.avail_in != 0 ) {
412412 if (0 != getdata_uns(bzdata.next_out, bzdata.avail_out,cb,context)) {
413413 BZ2_bzDecompressEnd(&bzdata);
2828 #include
2929
3030 // This variable is useful for situations where the pthread library has been
31 // compiled with weak linkage for its interface symbols. This allows the
31 // compiled with weak linkage for its interface symbols. This allows the
3232 // threading support to be turned off by simply not linking against -lpthread.
33 // In that situation, the value of pthread_mutex_init will be 0 and
33 // In that situation, the value of pthread_mutex_init will be 0 and
3434 // consequently pthread_enabled will be false. In such situations, all the
3535 // pthread operations become no-ops and the functions all return false. If
3636 // pthread_mutex_init does have an address, then mutex support is enabled.
4747 if (pthread_enabled)
4848 {
4949 // Declare the pthread_mutex data structures
50 pthread_mutex_t* mutex =
50 pthread_mutex_t* mutex =
5151 static_cast(malloc(sizeof(pthread_mutex_t)));
5252 pthread_mutexattr_t attr;
5353
9191 }
9292 }
9393
94 bool
94 bool
9595 Mutex::acquire()
9696 {
97 if (pthread_enabled)
97 if (pthread_enabled)
9898 {
9999 pthread_mutex_t* mutex = reinterpret_cast(data_);
100100 assert(mutex != 0);
105105 return false;
106106 }
107107
108 bool
108 bool
109109 Mutex::release()
110110 {
111111 if (pthread_enabled)
119119 return false;
120120 }
121121
122 bool
122 bool
123123 Mutex::tryacquire()
124124 {
125125 if (pthread_enabled)
168168 rv = getAlphaRegNumber(MO.getReg());
169169 } else if (MO.isImmediate()) {
170170 rv = MO.getImmedValue();
171 } else if (MO.isGlobalAddress() || MO.isExternalSymbol()
171 } else if (MO.isGlobalAddress() || MO.isExternalSymbol()
172172 || MO.isConstantPoolIndex()) {
173173 DEBUG(std::cerr << MO << " is a relocated op for " << MI << "\n";);
174 bool isExternal = MO.isExternalSymbol() ||
175 (MO.isGlobalAddress() &&
174 bool isExternal = MO.isExternalSymbol() ||
175 (MO.isGlobalAddress() &&
176176 ( MO.getGlobal()->hasWeakLinkage() ||
177177 MO.getGlobal()->isExternal()) );
178178 unsigned Reloc = 0;
212212 true));
213213 else
214214 MCE.addRelocation(MachineRelocation((unsigned)MCE.getCurrentPCOffset(),
215 Reloc, MO.getConstantPoolIndex(),
215 Reloc, MO.getConstantPoolIndex(),
216216 Offset));
217217 } else if (MO.isMachineBasicBlock()) {
218218 unsigned* CurrPC = (unsigned*)(intptr_t)MCE.getCurrentPCValue();
6363 //Move an Ireg to a FPreg
6464 ITOF,
6565 //Move a FPreg to an Ireg
66 FTOI,
66 FTOI,
6767 };
6868 }
6969 }
9292
9393 setOperationAction(ISD::EXTLOAD, MVT::i1, Promote);
9494 setOperationAction(ISD::EXTLOAD, MVT::f32, Expand);
95
95
9696 setOperationAction(ISD::ZEXTLOAD, MVT::i1, Promote);
9797 setOperationAction(ISD::ZEXTLOAD, MVT::i32, Expand);
9898
163163 virtual std::pair
164164 LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
165165 const Type *ArgTy, SelectionDAG &DAG);
166
166
167167 void restoreGP(MachineBasicBlock* BB)
168168 {
169169 BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP);
202202 } else {
203203 int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
204204 SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
205 SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other,
206 DAG.getEntryNode(), Op.getOperand(0),
205 SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other,
206 DAG.getEntryNode(), Op.getOperand(0),
207207 StackSlot, DAG.getSrcValue(NULL));
208208 SRC = DAG.getLoad(Op.getValueType(), Store.getValue(0), StackSlot,
209209 DAG.getSrcValue(NULL));
288288 case MVT::i16:
289289 case MVT::i32:
290290 case MVT::i64:
291 args_int[count] = AddLiveIn(MF, args_int[count],
291 args_int[count] = AddLiveIn(MF, args_int[count],
292292 getRegClassFor(MVT::i64));
293293 argt = DAG.getCopyFromReg(args_int[count], VT, DAG.getRoot());
294294 if (VT != MVT::i64)
321321 int FI = MFI->CreateFixedObject(8, -8 * (6 - i));
322322 if (i == 0) VarArgsBase = FI;
323323 SDOperand SDFI = DAG.getFrameIndex(FI, MVT::i64);
324 LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), argt,
324 LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), argt,
325325 SDFI, DAG.getSrcValue(NULL)));
326
326
327327 if (args_float[i] < 1024)
328328 args_float[i] = AddLiveIn(MF,args_float[i], getRegClassFor(MVT::f64));
329329 argt = DAG.getCopyFromReg(args_float[i], MVT::f64, DAG.getRoot());
330330 FI = MFI->CreateFixedObject(8, - 8 * (12 - i));
331331 SDFI = DAG.getFrameIndex(FI, MVT::i64);
332 LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), argt,
332 LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), argt,
333333 SDFI, DAG.getSrcValue(NULL)));
334334 }
335335
362362 AlphaTargetLowering::LowerCallTo(SDOperand Chain,
363363 const Type *RetTy, bool isVarArg,
364364 unsigned CallingConv, bool isTailCall,
365 SDOperand Callee, ArgListTy &Args,
365 SDOperand Callee, ArgListTy &Args,
366366 SelectionDAG &DAG) {
367367 int NumBytes = 0;
368368 if (Args.size() > 6)
412412 Value *VAListV, SelectionDAG &DAG) {
413413 // vastart stores the address of the VarArgsBase and VarArgsOffset
414414 SDOperand FR = DAG.getFrameIndex(VarArgsBase, MVT::i64);
415 SDOperand S1 = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP,
415 SDOperand S1 = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP,
416416 DAG.getSrcValue(VAListV));
417 SDOperand SA2 = DAG.getNode(ISD::ADD, MVT::i64, VAListP,
417 SDOperand SA2 = DAG.getNode(ISD::ADD, MVT::i64, VAListP,
418418 DAG.getConstant(8, MVT::i64));
419 return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, S1,
420 DAG.getConstant(VarArgsOffset, MVT::i64), SA2,
419 return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, S1,
420 DAG.getConstant(VarArgsOffset, MVT::i64), SA2,
421421 DAG.getSrcValue(VAListV, 8), DAG.getValueType(MVT::i32));
422422 }
423423
426426 const Type *ArgTy, SelectionDAG &DAG) {
427427 SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAListP,
428428 DAG.getSrcValue(VAListV));
429 SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAListP,
429 SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAListP,
430430 DAG.getConstant(8, MVT::i64));
431 SDOperand Offset = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Base.getValue(1),
431 SDOperand Offset = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Base.getValue(1),
432432 Tmp, DAG.getSrcValue(VAListV, 8), MVT::i32);
433433 SDOperand DataPtr = DAG.getNode(ISD::ADD, MVT::i64, Base, Offset);
434434 if (ArgTy->isFloatingPoint())
436436 //if fp && Offset < 6*8, then subtract 6*8 from DataPtr
437437 SDOperand FPDataPtr = DAG.getNode(ISD::SUB, MVT::i64, DataPtr,
438438 DAG.getConstant(8*6, MVT::i64));
439 SDOperand CC = DAG.getSetCC(ISD::SETLT, MVT::i64,
439 SDOperand CC = DAG.getSetCC(ISD::SETLT, MVT::i64,
440440 Offset, DAG.getConstant(8*6, MVT::i64));
441441 DataPtr = DAG.getNode(ISD::SELECT, MVT::i64, CC, FPDataPtr, DataPtr);
442442 }
449449 Result = DAG.getExtLoad(ISD::ZEXTLOAD, MVT::i64, Offset.getValue(1),
450450 DataPtr, DAG.getSrcValue(NULL), MVT::i32);
451451 else
452 Result = DAG.getLoad(getValueType(ArgTy), Offset.getValue(1), DataPtr,
452 Result = DAG.getLoad(getValueType(ArgTy), Offset.getValue(1), DataPtr,
453453 DAG.getSrcValue(NULL));
454454
455 SDOperand NewOffset = DAG.getNode(ISD::ADD, MVT::i64, Offset,
455 SDOperand NewOffset = DAG.getNode(ISD::ADD, MVT::i64, Offset,
456456 DAG.getConstant(8, MVT::i64));
457 SDOperand Update = DAG.getNode(ISD::TRUNCSTORE, MVT::Other,
458 Result.getValue(1), NewOffset,
457 SDOperand Update = DAG.getNode(ISD::TRUNCSTORE, MVT::Other,
458 Result.getValue(1), NewOffset,
459459 Tmp, DAG.getSrcValue(VAListV, 8),
460460 DAG.getValueType(MVT::i32));
461461 Result = DAG.getNode(ISD::TRUNCATE, getValueType(ArgTy), Result);
467467 SDOperand AlphaTargetLowering::
468468 LowerVACopy(SDOperand Chain, SDOperand SrcP, Value *SrcV, SDOperand DestP,
469469 Value *DestV, SelectionDAG &DAG) {
470 SDOperand Val = DAG.getLoad(getPointerTy(), Chain, SrcP,
470 SDOperand Val = DAG.getLoad(getPointerTy(), Chain, SrcP,
471471 DAG.getSrcValue(SrcV));
472472 SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
473473 Val, DestP, DAG.getSrcValue(DestV));
474 SDOperand NP = DAG.getNode(ISD::ADD, MVT::i64, SrcP,
474 SDOperand NP = DAG.getNode(ISD::ADD, MVT::i64, SrcP,
475475 DAG.getConstant(8, MVT::i64));
476476 Val = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Result, NP,
477477 DAG.getSrcValue(SrcV, 8), MVT::i32);
478 SDOperand NPD = DAG.getNode(ISD::ADD, MVT::i64, DestP,
478 SDOperand NPD = DAG.getNode(ISD::ADD, MVT::i64, DestP,
479479 DAG.getConstant(8, MVT::i64));
480480 return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Val.getValue(1),
481481 Val, NPD, DAG.getSrcValue(DestV, 8),
513513 int max_depth;
514514
515515 public:
516 AlphaISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering),
516 AlphaISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering),
517517 AlphaLowering(TM)
518518 {}
519519
534534 if(has_sym)
535535 ++count_ins;
536536 if(EnableAlphaCount)
537 std::cerr << "COUNT: "
538 << BB->getParent()->getFunction ()->getName() << " "
539 << BB->getNumber() << " "
537 std::cerr << "COUNT: "
538 << BB->getParent()->getFunction ()->getName() << " "
539 << BB->getNumber() << " "
540540 << max_depth << " "
541541 << count_ins << " "
542542 << count_outs << "\n";
545545 ExprMap.clear();
546546 CCInvMap.clear();
547547 }
548
548
549549 virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF);
550550
551551 unsigned SelectExpr(SDOperand N);
10311031 return;
10321032 }
10331033 } else { //FP
1034 //Any comparison between 2 values should be codegened as an folded
1034 //Any comparison between 2 values should be codegened as an folded
10351035 //branch, as moving CC to the integer register is very expensive
10361036 //for a cmp b: c = a - b;
10371037 //a = b: c = 0
12971297 case ISD::GlobalAddress:
12981298 AlphaLowering.restoreGP(BB);
12991299 has_sym = true;
1300
1300
13011301 Reg = Result = MakeReg(MVT::i64);
13021302
13031303 if (EnableAlphaLSMark)
15581558
15591559 switch (SetCC->getCondition()) {
15601560 default: Node->dump(); assert(0 && "Unknown integer comparison!");
1561 case ISD::SETEQ:
1561 case ISD::SETEQ:
15621562 Opc = isConst ? Alpha::CMPEQi : Alpha::CMPEQ; dir=1; break;
15631563 case ISD::SETLT:
15641564 Opc = isConst ? Alpha::CMPLTi : Alpha::CMPLT; dir = 1; break;
16741674 //Check operand(0) == Not
16751675 if (N.getOperand(0).getOpcode() == ISD::XOR &&
16761676 N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
1677 cast(N.getOperand(0).getOperand(1))->getSignExtended()
1677 cast(N.getOperand(0).getOperand(1))->getSignExtended()
16781678 == -1) {
16791679 switch(opcode) {
16801680 case ISD::AND: Opc = Alpha::BIC; break;
17291729 case ISD::SHL: Opc = Alpha::SL; break;
17301730 case ISD::SRL: Opc = Alpha::SRL; break;
17311731 case ISD::SRA: Opc = Alpha::SRA; break;
1732 case ISD::MUL:
1733 Opc = isFP ? (DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS)
1732 case ISD::MUL:
1733 Opc = isFP ? (DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS)
17341734 : Alpha::MULQ;
17351735 break;
17361736 };
18061806 }
18071807 else if((CSD = dyn_cast(N.getOperand(1))) &&
18081808 (int64_t)CSD->getValue() >= 255 &&
1809 (int64_t)CSD->getValue() <= 0)
1809 (int64_t)CSD->getValue() <= 0)
18101810 { //inverted imm add/sub
18111811 Opc = isAdd ? Alpha::SUBQi : Alpha::ADDQi;
18121812 Tmp1 = SelectExpr(N.getOperand(0));
19021902 }
19031903 Tmp1 = SelectExpr(N.getOperand(0));
19041904 Tmp2 = SelectExpr(N.getOperand(1));
1905 SDOperand Addr =
1905 SDOperand Addr =
19061906 ISelDAG->getExternalSymbol(opstr, AlphaLowering.getPointerTy());
19071907 Tmp3 = SelectExpr(Addr);
19081908 //set up regs explicitly (helps Reg alloc)
19461946 if (SetCC && !MVT::isInteger(SetCC->getOperand(0).getValueType()))
19471947 { //FP Setcc -> Select yay!
19481948
1949
1949
19501950 //for a cmp b: c = a - b;
19511951 //a = b: c = 0
19521952 //a < b: c < 0
19991999 // // Get the condition into the zero flag.
20002000 // BuildMI(BB, Alpha::FCMOVEQ, 3, Result).addReg(TV).addReg(FV).addReg(Tmp4);
20012001 return Result;
2002 }
2002 }
20032003 } else {
20042004 //FIXME: look at parent to decide if intCC can be folded, or if setCC(FP)
20052005 //and can save stack use
21152115 //re-get the val since we are going to mem anyway
21162116 val = (int64_t)cast(N)->getValue();
21172117 MachineConstantPool *CP = BB->getParent()->getConstantPool();
2118 ConstantUInt *C =
2118 ConstantUInt *C =
21192119 ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val);
21202120 unsigned CPI = CP->getConstantPoolIndex(C);
21212121 AlphaLowering.restoreGP(BB);
23162316 }
23172317
23182318 int i, j, k;
2319 if (EnableAlphaLSMark)
2320 getValueInfo(cast(N.getOperand(3))->getValue(),
2319 if (EnableAlphaLSMark)
2320 getValueInfo(cast(N.getOperand(3))->getValue(),
23212321 i, j, k);
23222322
23232323 GlobalAddressSDNode *GASD = dyn_cast(Address);
5858 void* CameFromOrig = (void*)*(oldsp - 2);
5959
6060 void* Target = JITCompilerFunction(CameFromStub);
61
61
6262 //rewrite the stub to an unconditional branch
6363 EmitBranchToAt(CameFromStub, Target, false);
6464
255255 case 0x08: //LDA
256256 assert(gpdistmap[make_pair(Function, MR->getConstantVal())] &&
257257 "LDAg without seeing LDAHg");
258 idx = &GOTBase[GOToffset * 8] -
258 idx = &GOTBase[GOToffset * 8] -
259259 (unsigned char*)gpdistmap[make_pair(Function, MR->getConstantVal())];
260260 idx = getLower16(idx);
261261 DEBUG(std::cerr << "LDA: " << idx << "\n");
225225 // Create the frame index object for this incoming parameter...
226226 ArgOffset = 16 + 8 * (count - 8);
227227 int FI = MFI->CreateFixedObject(8, ArgOffset);
228
228
229229 // Create the SelectionDAG nodes corresponding to a load
230230 //from this parameter
231231 SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64);
306306 IA64TargetLowering::LowerCallTo(SDOperand Chain,
307307 const Type *RetTy, bool isVarArg,
308308 unsigned CallingConv, bool isTailCall,
309 SDOperand Callee, ArgListTy &Args,
309 SDOperand Callee, ArgListTy &Args,
310310 SelectionDAG &DAG) {
311311
312312 MachineFunction &MF = DAG.getMachineFunction();
399399 "Other types should have been promoted for varargs!");
400400 Amt = 8;
401401 }
402 Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val,
402 Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val,
403403 DAG.getConstant(Amt, Val.getValueType()));
404404 Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain,
405405 Val, VAListP, DAG.getSrcValue(VAListV));
493493 int lim=inString.size();
494494
495495 while(curpos
496 if(inString[curpos]=='1') { // if we see a '1', look for a run of them
496 if(inString[curpos]=='1') { // if we see a '1', look for a run of them
497497 int runlength=0;
498498 std::string replaceString="N";
499
499
500500 // find the run length
501501 for(;inString[curpos+runlength]=='1';runlength++) ;
502502
503503 for(int i=0; i
504 replaceString+="0";
504 replaceString+="0";
505505 replaceString+="1";
506506
507507 if(runlength>1) {
508 inString.replace(curpos, runlength+1, replaceString);
509 curpos+=runlength-1;
508 inString.replace(curpos, runlength+1, replaceString);
509 curpos+=runlength-1;
510510 } else
511 curpos++;
511 curpos++;
512512 } else { // a zero, we just keep chugging along
513513 curpos++;
514514 }
528528
529529 struct shiftaddblob { // this encodes stuff like (x=) "A << B [+-] C << D"
530530 unsigned firstVal; // A
531 unsigned firstShift; // B
531 unsigned firstShift; // B
532532 unsigned secondVal; // C
533533 unsigned secondShift; // D
534534 bool isSub;
554554 }
555555
556556 std::vector p,n;
557
557
558558 for(int i=0; i<=length; i++) {
559559 if (s.c_str()[length-i]=='P') {
560560 p.push_back(i);
608608 int z=abs(int_d)-1;
609609
610610 if(int_d>0) {
611
611
612612 for(unsigned base=0; base
613 if( ((base+z+1) < retstring.size()) &&
614 retstring.c_str()[base]=='P' &&
615 retstring.c_str()[base+z+1]=='P')
616 {
617 // match
618 x++;
619 retstring.replace(base, 1, "0");
620 retstring.replace(base+z+1, 1, "p");
621 }
613 if( ((base+z+1) < retstring.size()) &&
614 retstring.c_str()[base]=='P' &&
615 retstring.c_str()[base+z+1]=='P')
616 {
617 // match
618 x++;
619 retstring.replace(base, 1, "0");
620 retstring.replace(base+z+1, 1, "p");
621 }
622622 }
623623
624624 for(unsigned base=0; base
625 if( ((base+z+1) < retstring.size()) &&
626 retstring.c_str()[base]=='N' &&
627 retstring.c_str()[base+z+1]=='N')
628 {
629 // match
630 x++;
631 retstring.replace(base, 1, "0");
632 retstring.replace(base+z+1, 1, "n");
633 }
625 if( ((base+z+1) < retstring.size()) &&
626 retstring.c_str()[base]=='N' &&
627 retstring.c_str()[base+z+1]=='N')
628 {
629 // match
630 x++;
631 retstring.replace(base, 1, "0");
632 retstring.replace(base+z+1, 1, "n");
633 }
634634 }
635635
636636 } else {
637637 for(unsigned base=0; base
638 if( ((base+z+1) < retstring.size()) &&
639 ((retstring.c_str()[base]=='P' &&
640 retstring.c_str()[base+z+1]=='N') ||
641 (retstring.c_str()[base]=='N' &&
642 retstring.c_str()[base+z+1]=='P')) ) {
643 // match
644 x++;
645
646 if(retstring.c_str()[base]=='P') {
647 retstring.replace(base, 1, "0");
648 retstring.replace(base+z+1, 1, "p");
649 } else { // retstring[base]=='N'
650 retstring.replace(base, 1, "0");
651 retstring.replace(base+z+1, 1, "n");
652 }
653 }
638 if( ((base+z+1) < retstring.size()) &&
639 ((retstring.c_str()[base]=='P' &&
640 retstring.c_str()[base+z+1]=='N') ||
641 (retstring.c_str()[base]=='N' &&
642 retstring.c_str()[base+z+1]=='P')) ) {
643 // match
644 x++;
645
646 if(retstring.c_str()[base]=='P') {
647 retstring.replace(base, 1, "0");
648 retstring.replace(base+z+1, 1, "p");
649 } else { // retstring[base]=='N'
650 retstring.replace(base, 1, "0");
651 retstring.replace(base+z+1, 1, "n");
652 }
653 }
654654 }
655655 }
656656
659659 t = retstring;
660660 c = int_d; // tofix
661661 }
662
662
663663 } d.pop_back(); // hmm
664664
665665 u = t;
666
666
667667 for(unsigned i=0; i
668668 if(t.c_str()[i]=='p' || t.c_str()[i]=='n')
669669 t.replace(i, 1, "0");
683683 c=-c;
684684 } else
685685 f=false;
686
686
687687 int pos=0;
688688 while(u[pos]=='0')
689689 pos++;
698698 bool isN=(u[p]=='N');
699699
700700 if(isP)
701 u.replace(p, 1, "N");
701 u.replace(p, 1, "N");
702702 if(isN)
703 u.replace(p, 1, "P");
703 u.replace(p, 1, "P");
704704 }
705705 }
706706
709709 int i = lefevre(u, ops);
710710
711711 shiftaddblob blob;
712
712
713713 blob.firstVal=i; blob.firstShift=c;
714714 blob.isSub=f;
715715 blob.secondVal=i; blob.secondShift=0;
730730 bool isN=(t.c_str()[p]=='N');
731731
732732 if(isP)
733 t.replace(p, 1, "N");
733 t.replace(p, 1, "N");
734734 if(isN)
735 t.replace(p, 1, "P");
735 t.replace(p, 1, "P");
736736 }
737737 }
738738
763763 break;
764764 //assert
765765 }
766
766
767767 ops.push_back(blob);
768768 return ops.size();
769769 }
807807
808808 assert(ops.size() < 80 && "constmul code has gone haywire\n");
809809 SDOperand results[80]; // temporary results (of adds/subs of shifts)
810
810
811811 // now turn 'ops' into DAG bits
812812 for(unsigned i=0; i
813813 SDOperand amt = ISelDAG->getConstant(ops[i].firstShift, MVT::i64);
829829 if(preliminaryShift) {
830830 SDOperand finalshift = ISelDAG->getConstant(preliminaryShift, MVT::i64);
831831 shiftedresult = ISelDAG->getNode(ISD::SHL, MVT::i64,
832 results[ops.size()-1], finalshift);
832 results[ops.size()-1], finalshift);
833833 } else { // there was no preliminary divide-by-power-of-2 required
834834 shiftedresult = results[ops.size()-1];
835835 }
836
836
837837 SDOperand finalresult;
838838 if(flippedSign) { // if we were multiplying by a negative constant:
839839 SDOperand zero = ISelDAG->getConstant(0, MVT::i64);
842842 } else { // there was no preliminary multiply by -1 required
843843 finalresult = shiftedresult;
844844 }
845
846 return finalresult;
845
846 return finalresult;
847847 }
848848
849849 /// ExactLog2 - This function solves for (Val == 1 << (N-1)) and returns N. It
10971097 .addReg(Tmp1);
10981098 break;
10991099 }
1100
1100
11011101 return Result;
11021102 }
11031103
13151315 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
13161316 int shl_amt = CSD->getValue();
13171317 Tmp3 = SelectExpr(N.getOperand(1));
1318
1318
13191319 BuildMI(BB, IA64::SHLADD, 3, Result)
13201320 .addReg(Tmp1).addImm(shl_amt).addReg(Tmp3);
13211321 return Result; // early exit
13431343
13441344 if(DestType != MVT::f64) { // TODO: speed!
13451345 if(N.getOperand(1).getOpcode() != ISD::Constant) { // if not a const mul
1346 // boring old integer multiply with xma
1347 Tmp1 = SelectExpr(N.getOperand(0));
1348 Tmp2 = SelectExpr(N.getOperand(1));
1349
1350 unsigned TempFR1=MakeReg(MVT::f64);
1351 unsigned TempFR2=MakeReg(MVT::f64);
1352 unsigned TempFR3=MakeReg(MVT::f64);
1353 BuildMI(BB, IA64::SETFSIG, 1, TempFR1).addReg(Tmp1);
1354 BuildMI(BB, IA64::SETFSIG, 1, TempFR2).addReg(Tmp2);
1355 BuildMI(BB, IA64::XMAL, 1, TempFR3).addReg(TempFR1).addReg(TempFR2)
1356 .addReg(IA64::F0);
1357 BuildMI(BB, IA64::GETFSIG, 1, Result).addReg(TempFR3);
1358 return Result; // early exit
1346 // boring old integer multiply with xma
1347 Tmp1 = SelectExpr(N.getOperand(0));
1348 Tmp2 = SelectExpr(N.getOperand(1));
1349
1350 unsigned TempFR1=MakeReg(MVT::f64);
1351 unsigned TempFR2=MakeReg(MVT::f64);
1352 unsigned TempFR3=MakeReg(MVT::f64);
1353 BuildMI(BB, IA64::SETFSIG, 1, TempFR1).addReg(Tmp1);
1354 BuildMI(BB, IA64::SETFSIG, 1, TempFR2).addReg(Tmp2);
1355 BuildMI(BB, IA64::XMAL, 1, TempFR3).addReg(TempFR1).addReg(TempFR2)
1356 .addReg(IA64::F0);
1357 BuildMI(BB, IA64::GETFSIG, 1, Result).addReg(TempFR3);
1358 return Result; // early exit
13591359 } else { // we are multiplying by an integer constant! yay
1360 return Reg = SelectExpr(BuildConstmulSequence(N)); // avert your eyes!
1360 return Reg = SelectExpr(BuildConstmulSequence(N)); // avert your eyes!
13611361 }
13621362 }
13631363 else { // floating point multiply
17981798 unsigned ModulusResult = MakeReg(MVT::f64);
17991799 unsigned TmpF = MakeReg(MVT::f64);
18001800 unsigned TmpI = MakeReg(MVT::i64);
1801
1801
18021802 BuildMI(BB, IA64::SUB, 2, TmpI).addReg(IA64::r0).addReg(Tmp2);
18031803 BuildMI(BB, IA64::SETFSIG, 1, TmpF).addReg(TmpI);
18041804 BuildMI(BB, IA64::XMAL, 3, ModulusResult)
18421842 Tmp2 = SelectExpr(N.getOperand(1));
18431843 } else // not comparing against a constant
18441844 Tmp2 = SelectExpr(N.getOperand(1));
1845
1845
18461846 switch (SetCC->getCondition()) {
18471847 default: assert(0 && "Unknown integer comparison!");
18481848 case ISD::SETEQ:
19551955 case MVT::i16: Opc = IA64::LD2; break;
19561956 case MVT::i32: Opc = IA64::LD4; break;
19571957 case MVT::i64: Opc = IA64::LD8; break;
1958
1958
19591959 case MVT::f32: Opc = IA64::LDF4; break;
19601960 case MVT::f64: Opc = IA64::LDF8; break;
19611961 }
20362036 BuildMI(BB, Opc, 1, dummy).addReg(Tmp2);
20372037 // we compare to 0. true? 0. false? 1.
20382038 BuildMI(BB, IA64::CMPNE, 2, Result).addReg(dummy).addReg(IA64::r0);
2039 }
2039 }
20402040 }
20412041
20422042 return Result;
21132113 for (int i = 8, e = argvregs.size(); i < e; ++i)
21142114 {
21152115 unsigned tempAddr = MakeReg(MVT::i64);
2116
2116
21172117 switch(N.getOperand(i+2).getValueType()) {
21182118 default:
21192119 Node->dump();
21562156 }
21572157 else { // otherwise we need to get the function descriptor
21582158 // load the branch target (function)'s entry point and
2159 // GP, then branch
2159 // GP, then branch
21602160 Tmp1 = SelectExpr(N.getOperand(1));
21612161
21622162 unsigned targetEntryPoint=MakeReg(MVT::i64);
23542354 case MVT::i16: Opc = IA64::ST2; break;
23552355 case MVT::i32: Opc = IA64::ST4; break;
23562356 case MVT::i64: Opc = IA64::ST8; break;
2357
2357
23582358 case MVT::f32: Opc = IA64::STF4; break;
23592359 case MVT::f64: Opc = IA64::STF8; break;
23602360 }
23932393 } else if(N.getOperand(2).getOpcode() == ISD::FrameIndex) {
23942394
23952395 // FIXME? (what about bools?)
2396
2396
23972397 unsigned dummy = MakeReg(MVT::i64);
23982398 BuildMI(BB, IA64::MOV, 1, dummy)
23992399 .addFrameIndex(cast(N.getOperand(2))->getIndex());
9191 if (OpcodeToReplace == PPC::COND_BRANCH) {
9292 MachineBasicBlock::iterator MBBJ = MBBI;
9393 ++MBBJ;
94
94
9595 // condbranch operands:
9696 // 0. CR0 register
9797 // 1. bc opcode
200200 case PPC::LIS:
201201 if (isExternal)
202202 Reloc = PPC::reloc_absolute_ptr_high; // Pointer to stub
203 else
203 else
204204 Reloc = PPC::reloc_absolute_high; // Pointer to symbol
205205 break;
206206 case PPC::LA:
220220 case PPC::STFD:
221221 if (isExternal)
222222 Reloc = PPC::reloc_absolute_ptr_low;
223 else
223 else
224224 Reloc = PPC::reloc_absolute_low;
225225 break;
226226 }
7676 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
7777 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
7878 }
79
79
8080 //PowerPC does not have CTPOP or CTTZ
8181 setOperationAction(ISD::CTPOP, MVT::i32 , Expand);
8282 setOperationAction(ISD::CTTZ , MVT::i32 , Expand);
102102
103103 virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
104104 Value *VAListV, SelectionDAG &DAG);
105
105
106106 virtual std::pair
107107 LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
108108 const Type *ArgTy, SelectionDAG &DAG);
109
109
110110 virtual std::pair
111111 LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
112112 SelectionDAG &DAG);
287287 std::pair
288288 PPC32TargetLowering::LowerCallTo(SDOperand Chain,
289289 const Type *RetTy, bool isVarArg,
290 unsigned CallingConv, bool isTailCall,
290 unsigned CallingConv, bool isTailCall,
291291 SDOperand Callee, ArgListTy &Args,
292292 SelectionDAG &DAG) {
293293 // args_to_use will accumulate outgoing args for the ISD::CALL case in
991991 bool ISel::SelectBitfieldInsert(SDOperand OR, unsigned Result) {
992992 bool IsRotate = false;
993993 unsigned TgtMask = 0xFFFFFFFF, InsMask = 0xFFFFFFFF, Amount = 0;
994
994
995995 SDOperand Op0 = OR.getOperand(0);
996996 SDOperand Op1 = OR.getOperand(1);
997997
10451045 // constant as its input, make that the inserted value so that we can combine
10461046 // the shift into the rotate part of the rlwimi instruction
10471047 if (Op0Opc == ISD::AND && Op1Opc == ISD::AND) {
1048 if (Op1.getOperand(0).getOpcode() == ISD::SHL ||
1048 if (Op1.getOperand(0).getOpcode() == ISD::SHL ||
10491049 Op1.getOperand(0).getOpcode() == ISD::SRL) {
1050 if (ConstantSDNode *CN =
1050 if (ConstantSDNode *CN =
10511051 dyn_cast(Op1.getOperand(0).getOperand(1).Val)) {
1052 Amount = Op1.getOperand(0).getOpcode() == ISD::SHL ?
1052 Amount = Op1.getOperand(0).getOpcode() == ISD::SHL ?
10531053 CN->getValue() : 32 - CN->getValue();
10541054 Tmp3 = SelectExpr(Op1.getOperand(0).getOperand(0));
10551055 }
10561056 } else if (Op0.getOperand(0).getOpcode() == ISD::SHL ||
10571057 Op0.getOperand(0).getOpcode() == ISD::SRL) {
1058 if (ConstantSDNode *CN =
1058 if (ConstantSDNode *CN =
10591059 dyn_cast(Op0.getOperand(0).getOperand(1).Val)) {
10601060 std::swap(Op0, Op1);
10611061 std::swap(TgtMask, InsMask);
1062 Amount = Op1.getOperand(0).getOpcode() == ISD::SHL ?
1062 Amount = Op1.getOperand(0).getOpcode() == ISD::SHL ?
10631063 CN->getValue() : 32 - CN->getValue();
10641064 Tmp3 = SelectExpr(Op1.getOperand(0).getOperand(0));
10651065 }
18771877 return SelectExpr(BuildSDIVSequence(N));
18781878 else
18791879 return SelectExpr(BuildUDIVSequence(N));
1880 }
1880 }
18811881 Tmp1 = SelectExpr(N.getOperand(0));
18821882 Tmp2 = SelectExpr(N.getOperand(1));
18831883 switch (DestType) {
135135 PICEnabled = false;
136136
137137 bool LP64 = (0 != dynamic_cast(&TM));
138
138
139139 if (EnablePPCLSR) {
140140 PM.add(createLoopStrengthReducePass());
141141 PM.add(createCFGSimplificationPass());
5252 return new FPMover (tm);
5353 }
5454
55 static void doubleToSingleRegPair(unsigned doubleReg, unsigned &singleReg1,
55 static void doubleToSingleRegPair(unsigned doubleReg, unsigned &singleReg1,
5656 unsigned &singleReg2) {
57 const unsigned EvenHalvesOfPairs[] = {
58 V8::F0, V8::F2, V8::F4, V8::F6, V8::F8, V8::F10, V8::F12, V8::F14,
59 V8::F16, V8::F18, V8::F20, V8::F22, V8::F24, V8::F26, V8::F28, V8::F30
57 const unsigned EvenHalvesOfPairs[] = {
58 V8::F0, V8::F2, V8::F4, V8::F6, V8::F8, V8::F10, V8::F12, V8::F14,
59 V8::F16, V8::F18, V8::F20, V8::F22, V8::F24, V8::F26, V8::F28, V8::F30
6060 };
61 const unsigned OddHalvesOfPairs[] = {
62 V8::F1, V8::F3, V8::F5, V8::F7, V8::F9, V8::F11, V8::F13, V8::F15,
63 V8::F17, V8::F19, V8::F21, V8::F23, V8::F25, V8::F27, V8::F29, V8::F31
61 const unsigned OddHalvesOfPairs[] = {
62 V8::F1, V8::F3, V8::F5, V8::F7, V8::F9, V8::F11, V8::F13, V8::F15,
63 V8::F17, V8::F19, V8::F21, V8::F23, V8::F25, V8::F27, V8::F29, V8::F31
6464 };
65 const unsigned DoubleRegsInOrder[] = {
66 V8::D0, V8::D1, V8::D2, V8::D3, V8::D4, V8::D5, V8::D6, V8::D7, V8::D8,
67 V8::D9, V8::D10, V8::D11, V8::D12, V8::D13, V8::D14, V8::D15
65 const unsigned DoubleRegsInOrder[] = {
66 V8::D0, V8::D1, V8::D2, V8::D3, V8::D4, V8::D5, V8::D6, V8::D7, V8::D8,
67 V8::D9, V8::D10, V8::D11, V8::D12, V8::D13, V8::D14, V8::D15
6868 };
6969 for (unsigned i = 0; i < sizeof(DoubleRegsInOrder)/sizeof(unsigned); ++i)
7070 if (DoubleRegsInOrder[i] == doubleReg) {
118118 std::vector
119119 V8TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
120120 {
121 static const unsigned IncomingArgRegs[] =
121 static const unsigned IncomingArgRegs[] =
122122 { V8::I0, V8::I1, V8::I2, V8::I3, V8::I4, V8::I5 };
123123 std::vector ArgValues;
124124
153153 case MVT::i8:
154154 case MVT::i16:
155155 case MVT::i32:
156 argt = DAG.getCopyFromReg(AddLiveIn(MF, IncomingArgRegs[ArgNo],
157 getRegClassFor(MVT::i32)),
156 argt = DAG.getCopyFromReg(AddLiveIn(MF, IncomingArgRegs[ArgNo],
157 getRegClassFor(MVT::i32)),
158158 VT, DAG.getRoot());
159159 if (VT != MVT::i32)
160160 argt = DAG.getNode(ISD::TRUNCATE, VT, argt);
197197 V8TargetLowering::LowerCallTo(SDOperand Chain,
198198 const Type *RetTy, bool isVarArg,
199199 unsigned CallingConv, bool isTailCall,
200 SDOperand Callee, ArgListTy &Args,
200 SDOperand Callee, ArgListTy &Args,
201201 SelectionDAG &DAG) {
202202 //FIXME
203203 return std::make_pair(Chain, Chain);
242242 // Clear state used for selection.
243243 ExprMap.clear();
244244 }
245
245
246246 virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF);
247247
248248 unsigned SelectExpr(SDOperand N);
346346 case MVT::f64: Opc = V8::LDFSRrr;
347347 case MVT::f32: Opc = V8::LDDFrr;
348348 default:
349 Node->dump();
349 Node->dump();
350350 assert(0 && "Bad type!");
351351 break;
352352 }
373373 SDOperand Chain = N.getOperand(0);
374374 Select(Chain);
375375 unsigned r = dyn_cast(Node)->getReg();
376
376
377377 BuildMI(BB, V8::ORrr, 2, Result).addReg(r).addReg(V8::G0);
378378 return Result;
379379 }
410410 Tmp2 = SelectExpr(N.getOperand(1));
411411 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
412412 return Result;
413
413
414414 }
415415 return 0;
416416 }
487487 Tmp1 = SelectExpr(Value);
488488 Tmp2 = SelectExpr(Address);
489489
490 unsigned VT = opcode == ISD::STORE ?
490 unsigned VT = opcode == ISD::STORE ?
491491 Value.getValueType() : cast(Node->getOperand(4))->getVT();
492492 switch(VT) {
493493 default: assert(0 && "unknown Type in store");
5252 return new FPMover (tm);
5353 }
5454
55 static void doubleToSingleRegPair(unsigned doubleReg, unsigned &singleReg1,
55 static void doubleToSingleRegPair(unsigned doubleReg, unsigned &singleReg1,
5656 unsigned &singleReg2) {
57 const unsigned EvenHalvesOfPairs[] = {
58 V8::F0, V8::F2, V8::F4, V8::F6, V8::F8, V8::F10, V8::F12, V8::F14,
59 V8::F16, V8::F18, V8::F20, V8::F22, V8::F24, V8::F26, V8::F28, V8::F30
57 const unsigned EvenHalvesOfPairs[] = {
58 V8::F0, V8::F2, V8::F4, V8::F6, V8::F8, V8::F10, V8::F12, V8::F14,
59 V8::F16, V8::F18, V8::F20, V8::F22, V8::F24, V8::F26, V8::F28, V8::F30
6060 };
61 const unsigned OddHalvesOfPairs[] = {
62 V8::F1, V8::F3, V8::F5, V8::F7, V8::F9, V8::F11, V8::F13, V8::F15,
63 V8::F17, V8::F19, V8::F21, V8::F23, V8::F25, V8::F27, V8::F29, V8::F31
61 const unsigned OddHalvesOfPairs[] = {
62 V8::F1, V8::F3, V8::F5, V8::F7, V8::F9, V8::F11, V8::F13, V8::F15,
63 V8::F17, V8::F19, V8::F21, V8::F23, V8::F25, V8::F27, V8::F29, V8::F31
6464 };
65 const unsigned DoubleRegsInOrder[] = {
66 V8::D0, V8::D1, V8::D2, V8::D3, V8::D4, V8::D5, V8::D6, V8::D7, V8::D8,
67 V8::D9, V8::D10, V8::D11, V8::D12, V8::D13, V8::D14, V8::D15
65 const unsigned DoubleRegsInOrder[] = {
66 V8::D0, V8::D1, V8::D2, V8::D3, V8::D4, V8::D5, V8::D6, V8::D7, V8::D8,
67 V8::D9, V8::D10, V8::D11, V8::D12, V8::D13, V8::D14, V8::D15
6868 };
6969 for (unsigned i = 0; i < sizeof(DoubleRegsInOrder)/sizeof(unsigned); ++i)
7070 if (DoubleRegsInOrder[i] == doubleReg) {
118118 std::vector
119119 V8TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG)
120120 {
121 static const unsigned IncomingArgRegs[] =
121 static const unsigned IncomingArgRegs[] =
122122 { V8::I0, V8::I1, V8::I2, V8::I3, V8::I4, V8::I5 };
123123 std::vector ArgValues;
124124
153153 case MVT::i8:
154154 case MVT::i16:
155155 case MVT::i32:
156 argt = DAG.getCopyFromReg(AddLiveIn(MF, IncomingArgRegs[ArgNo],
157 getRegClassFor(MVT::i32)),
156 argt = DAG.getCopyFromReg(AddLiveIn(MF, IncomingArgRegs[ArgNo],
157 getRegClassFor(MVT::i32)),
158158 VT, DAG.getRoot());
159159 if (VT != MVT::i32)
160160 argt = DAG.getNode(ISD::TRUNCATE, VT, argt);
197197 V8TargetLowering::LowerCallTo(SDOperand Chain,
198198 const Type *RetTy, bool isVarArg,
199199 unsigned CallingConv, bool isTailCall,
200 SDOperand Callee, ArgListTy &Args,
200 SDOperand Callee, ArgListTy &Args,
201201 SelectionDAG &DAG) {
202202 //FIXME
203203 return std::make_pair(Chain, Chain);
242242 // Clear state used for selection.
243243 ExprMap.clear();
244244 }
245
245
246246 virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF);
247247
248248 unsigned SelectExpr(SDOperand N);
346346 case MVT::f64: Opc = V8::LDFSRrr;
347347 case MVT::f32: Opc = V8::LDDFrr;
348348 default:
349 Node->dump();
349 Node->dump();
350350 assert(0 && "Bad type!");
351351 break;
352352 }
373373 SDOperand Chain = N.getOperand(0);
374374 Select(Chain);
375375 unsigned r = dyn_cast(Node)->getReg();
376
376
377377 BuildMI(BB, V8::ORrr, 2, Result).addReg(r).addReg(V8::G0);
378378 return Result;
379379 }
410410 Tmp2 = SelectExpr(N.getOperand(1));
411411 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
412412 return Result;
413
413
414414 }
415415 return 0;
416416 }
487487 Tmp1 = SelectExpr(Value);
488488 Tmp2 = SelectExpr(Address);
489489
490 unsigned VT = opcode == ISD::STORE ?
490 unsigned VT = opcode == ISD::STORE ?
491491 Value.getValueType() : cast(Node->getOperand(4))->getVT();
492492 switch(VT) {
493493 default: assert(0 && "unknown Type in store");
671671 && ! S.schedPrio.nodeIsReady(*SI))
672672 {
673673 // successor not scheduled and not marked ready; check *its* preds.
674
674
675675 bool succIsReady = true;
676676 for (sg_pred_const_iterator P=pred_begin(*SI); P != pred_end(*SI); ++P)
677677 if (! (*P)->isDummyNode() && ! S.isScheduled(*P)) {
678678 succIsReady = false;
679679 break;
680680 }
681
681
682682 if (succIsReady) // add the successor to the ready list
683683 S.schedPrio.insertReady(*SI);
684684 }
827827 S.addChoiceToSlot(s, S.getChoice(i));
828828 noSlotFound = false;
829829 }
830
830
831831 // No slot before `delayedNodeSlot' was found for this opCode
832832 // Use a later slot, and allow some delay slots to fall in
833833 // the next cycle.
837837 S.addChoiceToSlot(s, S.getChoice(i));
838838 break;
839839 }
840
840
841841 assert(s < S.nslots && "No feasible slot for instruction?");
842
842
843843 highestSlotUsed = std::max(highestSlotUsed, (int) s);
844844 }
845845
866866 const SchedGraphNode* breakingNode=S.getChoice(indexForBreakingNode);
867867 unsigned breakingSlot = INT_MAX;
868868 unsigned int nslotsToUse = S.nslots;
869
869
870870 // Find the last possible slot for this instruction.
871871 for (int s = S.nslots-1; s >= (int) startSlot; s--)
872872 if (S.schedInfo.instrCanUseSlot(breakingNode->getOpcode(), s)) {
883883 i < S.getNumChoices() && i < indexForBreakingNode; i++)
884884 {
885885 MachineOpCode opCode =S.getChoice(i)->getOpcode();
886
886
887887 // If a higher priority instruction cannot be assigned to
888888 // any earlier slots, don't schedule the breaking instruction.
889889 //
895895 foundLowerSlot = true;
896896 nslotsToUse = breakingSlot; // RESETS LOOP UPPER BOUND!
897897 }
898
898
899899 S.addChoiceToSlot(s, S.getChoice(i));
900900 }
901
901
902902 if (!foundLowerSlot)
903903 breakingSlot = INT_MAX; // disable breaking instr
904904 }
911911 nslotsToUse = breakingSlot;
912912 } else
913913 nslotsToUse = S.nslots;
914
914
915915 // For lower priority instructions than the one that breaks the
916916 // group, only assign them to slots lower than the breaking slot.
917917 // Otherwise, just ignore the instruction.
11971197 sdelayNodeVec.push_back(graph->getGraphNodeForInstr(MBBI));
11981198 else {
11991199 nopNodeVec.push_back(graph->getGraphNodeForInstr(MBBI));
1200
1200
12011201 //remove the MI from the Machine Code For Instruction
12021202 const TerminatorInst *TI = MBB.getBasicBlock()->getTerminator();
12031203 MachineCodeForInstruction& llvmMvec =
13491349 nextTime++;
13501350 }
13511351 } while (S.isched.getInstr(nextSlot, nextTime) != NULL);
1352
1352
13531353 S.scheduleInstr(delayNodeVec[i], nextSlot, nextTime);
13541354 break;
13551355 }
14561456
14571457 bool InstructionSchedulingWithSSA::runOnFunction(Function &F)
14581458 {
1459 SchedGraphSet graphSet(&F, target);
1459 SchedGraphSet graphSet(&F, target);
14601460
14611461 if (SchedDebugLevel >= Sched_PrintSchedGraphs) {
14621462 std::cerr << "\n*** SCHEDULING GRAPHS FOR INSTRUCTION SCHEDULING\n";
364364 new SchedGraphEdge(prevNode, node, regNum,
365365 SchedGraphEdge::AntiDep);
366366 }
367
367
368368 if (prevIsDef)
369369 if (!isDef || isDefAndUse)
370370 new SchedGraphEdge(prevNode, node, regNum,
645645 this->addMachineRegEdges(regToRefVecMap, target);
646646
647647 // Finally, add edges from the dummy root and to dummy leaf
648 this->addDummyEdges();
648 this->addDummyEdges();
649649 }
650650
651651
690690 << sink->getNodeId() << "] : ";
691691
692692 switch(depType) {
693 case SchedGraphEdge::CtrlDep:
693 case SchedGraphEdge::CtrlDep:
694694 os<< "Control Dep";
695695 break;
696696 case SchedGraphEdge::ValueDep:
697697 os<< "Reg Value " << *val;
698698 break;
699 case SchedGraphEdge::MemoryDep:
699 case SchedGraphEdge::MemoryDep:
700700 os<< "Memory Dep";
701701 break;
702702 case SchedGraphEdge::MachineRegister:
172172
173173 void SchedGraphCommon::eraseIncidentEdges(SchedGraphNodeCommon* node,
174174 bool addDummyEdges) {
175 this->eraseIncomingEdges(node, addDummyEdges);
176 this->eraseOutgoingEdges(node, addDummyEdges);
175 this->eraseIncomingEdges(node, addDummyEdges);
176 this->eraseOutgoingEdges(node, addDummyEdges);
177177 }
178178
179179 } // End llvm namespace
172172 inline int
173173 SchedPriorities::chooseByRule3(std::vector& mcands) {
174174 assert(mcands.size() >= 1 && "Should have at least one candidate here.");
175 int maxUses = candsAsHeap.getNode(mcands[0])->getNumOutEdges();
175 int maxUses = candsAsHeap.getNode(mcands[0])->getNumOutEdges();
176176 int indexWithMaxUses = 0;
177177 for (unsigned i=1, N = mcands.size(); i < N; i++) {
178178 int numUses = candsAsHeap.getNode(mcands[i])->getNumOutEdges();
8181 if (MI->getOpcode() == V9::PHI) { // for a phi node
8282 const Value *ArgVal = Op;
8383 const BasicBlock *PredBB = cast(*++OpI); // next ptr is BB
84
84
8585 PredToEdgeInSetMap[PredBB].insert(ArgVal);
86
86
8787 if (DEBUG_LV >= LV_DEBUG_Verbose)
8888 std::cerr << " - phi operand " << RAV(ArgVal) << " came from BB "
8989 << RAV(PredBB) << "\n";
110110 }
111111
112112
113
113
114114 //-----------------------------------------------------------------------------
115115 // To add an operand which is a def
116116 //-----------------------------------------------------------------------------
2424
2525 /// Create ModuloSchedulingPass
2626 FunctionPass *createDependenceAnalyzer() {
27 return new DependenceAnalyzer();
27 return new DependenceAnalyzer();
2828 }
2929 }
3030
3131 Statistic<> NoDeps("depanalyzer-nodeps", "Number of dependences eliminated");
32 Statistic<> NumDeps("depanalyzer-deps",
32 Statistic<> NumDeps("depanalyzer-deps",
3333 "Number of dependences could not eliminate");
34 Statistic<> AdvDeps("depanalyzer-advdeps",
34 Statistic<> AdvDeps("depanalyzer-advdeps",
3535 "Number of dependences using advanced techniques");
3636
3737 bool DependenceAnalyzer::runOnFunction(Function &F) {
4242 return false;
4343 }
4444
45 static RegisterAnalysisX("depanalyzer",
45 static RegisterAnalysisX("depanalyzer",
4646 "Dependence Analyzer");
47
47
4848 // - Get inter and intra dependences between loads and stores
4949 //
50 // Overview of Method:
51 // Step 1: Use alias analysis to determine dependencies if values are loop
52 // invariant
53 // Step 2: If pointers are not GEP, then there is a dependence.
54 // Step 3: Compare GEP base pointers with AA. If no alias, no dependence.
55 // If may alias, then add a dependence. If must alias, then analyze
56 // further (Step 4)
50 // Overview of Method:
51 // Step 1: Use alias analysis to determine dependencies if values are loop
52 // invariant
53 // Step 2: If pointers are not GEP, then there is a dependence.
54 // Step 3: Compare GEP base pointers with AA. If no alias, no dependence.
55 // If may alias, then add a dependence. If must alias, then analyze
56 // further (Step 4)
5757 // Step 4: do advanced analysis
58 void DependenceAnalyzer::AnalyzeDeps(Value *val, Value *val2, bool valLoad,
59 bool val2Load,
60 std::vector &deps,
61 BasicBlock *BB,
58 void DependenceAnalyzer::AnalyzeDeps(Value *val, Value *val2, bool valLoad,
59 bool val2Load,
60 std::vector &deps,
61 BasicBlock *BB,
6262 bool srcBeforeDest) {
63
63
6464 bool loopInvariant = true;
6565
6666 //Check if both are instructions and prove not loop invariant if possible
7070 if(Instruction *val2Inst = dyn_cast(val2))
7171 if(val2Inst->getParent() == BB)
7272 loopInvariant = false;
73
74
73
74
7575 //If Loop invariant, let AA decide
7676 if(loopInvariant) {
7777 if(AA->alias(val, (unsigned)TD->getTypeSize(val->getType()),
8383 ++NoDeps;
8484 return;
8585 }
86
86
8787 //Otherwise, continue with step 2
8888
8989 GetElementPtrInst *GP = dyn_cast(val);
119119
120120
121121 // advancedDepAnalysis - Do advanced data dependence tests
122 void DependenceAnalyzer::advancedDepAnalysis(GetElementPtrInst *gp1,
122 void DependenceAnalyzer::advancedDepAnalysis(GetElementPtrInst *gp1,
123123 GetElementPtrInst *gp2,
124124 bool valLoad,
125125 bool val2Load,
138138 if(Constant *c2 = dyn_cast(gp2->getOperand(1)))
139139 if(c1->isNullValue() && c2->isNullValue())
140140 GPok = true;
141
141
142142 if(!GPok) {
143143 createDep(deps, valLoad, val2Load, srcBeforeDest);
144144 return;
152152 Gep1Idx = c1->getOperand(0);
153153 if(CastInst *c2 = dyn_cast(Gep2Idx))
154154 Gep2Idx = c2->getOperand(0);
155
155
156156 //Get SCEV for each index into the area
157157 SCEVHandle SV1 = SE->getSCEV(Gep1Idx);
158158 SCEVHandle SV2 = SE->getSCEV(Gep2Idx);
187187 createDep(deps, valLoad, val2Load, srcBeforeDest);
188188 return;
189189 }
190
190
191191 if(B1->getValue()->getRawValue() != 1 || B2->getValue()->getRawValue() != 1) {
192192 createDep(deps, valLoad, val2Load, srcBeforeDest);
193193 return;
213213 ++NoDeps;
214214 return;
215215 }
216
216
217217 //Find constant index difference
218218 int diff = A1->getValue()->getRawValue() - A2->getValue()->getRawValue();
219219 //std::cerr << diff << "\n";
222222
223223 if(diff > 0)
224224 createDep(deps, valLoad, val2Load, srcBeforeDest, diff);
225
225
226226 //assert(diff > 0 && "Expected diff to be greater then 0");
227227 }
228228
229229 // Create dependences once its determined these two instructions
230230 // references the same memory
231 void DependenceAnalyzer::createDep(std::vector &deps,
232 bool valLoad, bool val2Load,
231 void DependenceAnalyzer::createDep(std::vector &deps,
232 bool valLoad, bool val2Load,
233233 bool srcBeforeDest, int diff) {
234234
235235 //If the source instruction occurs after the destination instruction
239239
240240 //If load/store pair
241241 if(valLoad && !val2Load) {
242 if(srcBeforeDest)
242 if(srcBeforeDest)
243243 //Anti Dep
244244 deps.push_back(Dependence(diff, Dependence::AntiDep));
245245 else
249249 }
250250 //If store/load pair
251251 else if(!valLoad && val2Load) {
252 if(srcBeforeDest)
252 if(srcBeforeDest)
253253 //True Dep
254254 deps.push_back(Dependence(diff, Dependence::TrueDep));
255255 else
265265 }
266266
267267
268
268
269269 //Get Dependence Info for a pair of Instructions
270 DependenceResult DependenceAnalyzer::getDependenceInfo(Instruction *inst1,
271 Instruction *inst2,
270 DependenceResult DependenceAnalyzer::getDependenceInfo(Instruction *inst1,
271 Instruction *inst2,
272272 bool srcBeforeDest) {
273273 std::vector deps;
274274
280280 return DependenceResult(deps);
281281
282282 if(LoadInst *ldInst = dyn_cast(inst1)) {
283
283
284284 if(StoreInst *stInst = dyn_cast(inst2))
285 AnalyzeDeps(ldInst->getOperand(0), stInst->getOperand(1),
285 AnalyzeDeps(ldInst->getOperand(0), stInst->getOperand(1),
286286 true, false, deps, ldInst->getParent(), srcBeforeDest);
287287 }
288288 else if(StoreInst *stInst = dyn_cast(inst1)) {
289
289
290290 if(LoadInst *ldInst = dyn_cast(inst2))
291 AnalyzeDeps(stInst->getOperand(1), ldInst->getOperand(0), false, true,
291 AnalyzeDeps(stInst->getOperand(1), ldInst->getOperand(0), false, true,
292292 deps, ldInst->getParent(), srcBeforeDest);
293
293
294294 else if(StoreInst *stInst2 = dyn_cast(inst2))
295 AnalyzeDeps(stInst->getOperand(1), stInst2->getOperand(1), false, false,
295 AnalyzeDeps(stInst->getOperand(1), stInst2->getOperand(1), false, false,
296296 deps, stInst->getParent(), srcBeforeDest);
297297 }
298298 else
299299 assert(0 && "Expected a load or a store\n");
300
300
301301 DependenceResult dr = DependenceResult(deps);
302302 return dr;
303303 }
2020 using namespace llvm;
2121
2222 //Check if all resources are free
23 bool resourcesFree(MSchedGraphNode*, int,
23 bool resourcesFree(MSchedGraphNode*, int,
2424 std::map > &resourceNumPerCycle);
2525
2626 //Returns a boolean indicating if the start cycle needs to be increased/decreased
8383 isFree = false;
8484 }
8585 }
86
86
8787 return isFree;
8888 }
8989
9090 void MSSchedule::useResource(int resourceNum, int cycle) {
91
91
9292 //Get Map for this cycle
9393 if(resourceNumPerCycle.count(cycle)) {
9494 if(resourceNumPerCycle[cycle].count(resourceNum)) {
104104 resourceUse[resourceNum] = 1;
105105 resourceNumPerCycle[cycle] = resourceUse;
106106 }
107
107
108108 }
109109
110110 bool MSSchedule::resourcesFree(MSchedGraphNode *node, int cycle, int II) {
128128 //Now check all cycles for conflicts
129129 for(int index = 0; index < (int) cyclesMayConflict.size(); ++index) {
130130 currentCycle = cyclesMayConflict[index];
131
131
132132 //Get resource usage for this instruction
133133 InstrRUsage rUsage = msi->getInstrRUsage(node->getInst()->getOpcode());
134134 std::vector > resources = rUsage.resourcesByCycle;
135
135
136136 //Loop over resources in each cycle and increments their usage count
137137 for(unsigned i=0; i < resources.size(); ++i) {
138138 for(unsigned j=0; j < resources[i].size(); ++j) {
139
139
140140 //Get Resource to check its availability
141141 int resourceNum = resources[i][j];
142
142
143143 DEBUG(std::cerr << "Attempting to schedule Resource Num: " << resourceNum << " in cycle: " << currentCycle << "\n");
144
145 success = resourceAvailable(resourceNum, currentCycle);
146
144
145 success = resourceAvailable(resourceNum, currentCycle);
146
147147 if(!success)
148148 break;
149
150 }
151
149
150 }
151
152152 if(!success)
153153 break;
154
154
155155 //Increase cycle
156156 currentCycle++;
157157 }
158
158
159159 if(!success)
160160 return false;
161161 }
167167 //Get resource usage for this instruction
168168 InstrRUsage rUsage = msi->getInstrRUsage(node->getInst()->getOpcode());
169169 std::vector > resources = rUsage.resourcesByCycle;
170
170
171171 //Loop over resources in each cycle and increments their usage count
172172 for(unsigned i=0; i < resources.size(); ++i) {
173173 for(unsigned j=0; j < resources[i].size(); ++j) {
194194
195195 //Using the schedule, fold up into kernel and check resource conflicts as we go
196196 std::vector > tempKernel;
197
197
198198 int stageNum = ((schedule.rbegin()->first-offset)+1)/ II;
199199 int maxSN = 0;
200200
211211
212212 tempKernel.push_back(std::make_pair(*I, count));
213213 maxSN = std::max(maxSN, count);
214
214
215215 }
216216 }
217217 ++count;
285285 }
286286 }
287287 }
288
288
289289 assert(0 && "We should always have found the def in our kernel\n");
290290 }
291291
2020 using namespace llvm;
2121
2222 //Check if all resources are free
23 bool resourcesFree(MSchedGraphSBNode*, int,
23 bool resourcesFree(MSchedGraphSBNode*, int,
2424 std::map > &resourceNumPerCycle);
2525
2626 //Returns a boolean indicating if the start cycle needs to be increased/decreased
8383 isFree = false;
8484 }
8585 }
86
86
8787 return isFree;
8888 }
8989
9090 void MSScheduleSB::useResource(int resourceNum, int cycle) {
91
91
9292 //Get Map for this cycle
9393 if(resourceNumPerCycle.count(cycle)) {
9494 if(resourceNumPerCycle[cycle].count(resourceNum)) {
104104 resourceUse[resourceNum] = 1;
105105 resourceNumPerCycle[cycle] = resourceUse;
106106 }
107
107
108108 }
109109
110110 bool MSScheduleSB::resourcesFree(MSchedGraphSBNode *node, int cycle, int II) {
128128 //Now check all cycles for conflicts
129129 for(int index = 0; index < (int) cyclesMayConflict.size(); ++index) {
130130 currentCycle = cyclesMayConflict[index];
131
131
132132 //Get resource usage for this instruction
133133 InstrRUsage rUsage = msi->getInstrRUsage(node->getInst()->getOpcode());
134134 std::vector > resources = rUsage.resourcesByCycle;
135
135
136136 //Loop over resources in each cycle and increments their usage count
137137 for(unsigned i=0; i < resources.size(); ++i) {
138138 for(unsigned j=0; j < resources[i].size(); ++j) {
139
139
140140 //Get Resource to check its availability
141141 int resourceNum = resources[i][j];
142
142
143143 DEBUG(std::cerr << "Attempting to schedule Resource Num: " << resourceNum << " in cycle: " << currentCycle << "\n");
144
145 success = resourceAvailable(resourceNum, currentCycle);
146
144
145 success = resourceAvailable(resourceNum, currentCycle);
146
147147 if(!success)
148148 break;
149
150 }
151
149
150 }
151
152152 if(!success)
153153 break;
154
154
155155 //Increase cycle
156156 currentCycle++;
157157 }
158
158
159159 if(!success)
160160 return false;
161161 }
167167 //Get resource usage for this instruction
168168 InstrRUsage rUsage = msi->getInstrRUsage(node->getInst()->getOpcode());
169169 std::vector > resources = rUsage.resourcesByCycle;
170
170
171171 //Loop over resources in each cycle and increments their usage count
172172 for(unsigned i=0; i < resources.size(); ++i) {
173173 for(unsigned j=0; j < resources[i].size(); ++j) {
194194
195195 //Using the schedule, fold up into kernel and check resource conflicts as we go
196196 std::vector > tempKernel;
197
197
198198 int stageNum = ((schedule.rbegin()->first-offset)+1)/ II;
199199 int maxSN = 0;
200200
211211
212212 tempKernel.push_back(std::make_pair(*I, count));
213213 maxSN = std::max(maxSN, count);
214
214
215215 }
216216 }
217217 ++count;
292292 }
293293 }
294294 }
295
295
296296 assert(0 && "We should always have found the def in our kernel\n");
297297 }
298298
3333 //MSchedGraphNode constructor
3434 MSchedGraphNode::MSchedGraphNode(const MachineInstr* inst,
3535 MSchedGraph *graph, unsigned idx,
36 unsigned late, bool isBranch)
37 : Inst(inst), Parent(graph), index(idx), latency(late),
36 unsigned late, bool isBranch)
37 : Inst(inst), Parent(graph), index(idx), latency(late),
3838 isBranchInstr(isBranch) {
3939
4040 //Add to the graph
7474
7575 //Get the iteration difference for the edge from this node to its successor
7676 unsigned MSchedGraphNode::getIteDiff(MSchedGraphNode *succ) {
77 for(std::vector::iterator I = Successors.begin(),
77 for(std::vector::iterator I = Successors.begin(),
7878 E = Successors.end();
7979 I != E; ++I) {
8080 if(I->getDest() == succ)
8888 //Loop over all the successors of our predecessor
8989 //return the edge the corresponds to this in edge
9090 int count = 0;
91 for(MSchedGraphNode::succ_iterator I = pred->succ_begin(),
91 for(MSchedGraphNode::succ_iterator I = pred->succ_begin(),
9292 E = pred->succ_end();
9393 I != E; ++I) {
9494 if(*I == this)
109109
110110 //Dtermine if pred is a predecessor of this node
111111 bool MSchedGraphNode::isPredecessor(MSchedGraphNode *pred) {
112 if(std::find( Predecessors.begin(), Predecessors.end(),
112 if(std::find( Predecessors.begin(), Predecessors.end(),
113113 pred) != Predecessors.end())
114114 return true;
115115 else
147147 //we ignore instructions associated to the index variable since this
148148 //is a special case in Modulo Scheduling. We only want to deal with
149149 //the body of the loop.
150 MSchedGraph::MSchedGraph(const MachineBasicBlock *bb,
151 const TargetMachine &targ,
152 std::map &ignoreInstrs,
153 DependenceAnalyzer &DA,
150 MSchedGraph::MSchedGraph(const MachineBasicBlock *bb,
151 const TargetMachine &targ,
152 std::map &ignoreInstrs,
153 DependenceAnalyzer &DA,
154154 std::map &machineTollvm)
155155 : Target(targ) {
156156
158158 assert(bb != NULL && "Basic Block is null");
159159
160160 BBs.push_back(bb);
161
161
162162 //Create nodes and edges for this BB
163163 buildNodesAndEdges(ignoreInstrs, DA, machineTollvm);
164164
170170 //we ignore instructions associated to the index variable since this
171171 //is a special case in Modulo Scheduling. We only want to deal with
172172 //the body of the loop.
173 MSchedGraph::MSchedGraph(std::vector &bbs,
174 const TargetMachine &targ,
175 std::map &ignoreInstrs,
176 DependenceAnalyzer &DA,
173 MSchedGraph::MSchedGraph(std::vector &bbs,
174 const TargetMachine &targ,
175 std::map &ignoreInstrs,
176 DependenceAnalyzer &DA,
177177 std::map &machineTollvm)
178178 : BBs(bbs), Target(targ) {
179179
180180 //Make sure there is at least one BB and it is not null,
181181 assert(((bbs.size() >= 1) && bbs[1] != NULL) && "Basic Block is null");
182
182
183183 //Create nodes and edges for this BB
184184 buildNodesAndEdges(ignoreInstrs, DA, machineTollvm);
185185
189189
190190
191191 //Copies the graph and keeps a map from old to new nodes
192 MSchedGraph::MSchedGraph(const MSchedGraph &G,
193 std::map &newNodes)
192 MSchedGraph::MSchedGraph(const MSchedGraph &G,
193 std::map &newNodes)
194194 : Target(G.Target) {
195195
196196 BBs = G.BBs;
197197
198198 std::map oldToNew;
199199 //Copy all nodes
200 for(MSchedGraph::const_iterator N = G.GraphMap.begin(),
200 for(MSchedGraph::const_iterator N = G.GraphMap.begin(),
201201 NE = G.GraphMap.end(); N != NE; ++N) {
202202
203203 MSchedGraphNode *newNode = new MSchedGraphNode(*(N->second));
207207 }
208208
209209 //Loop over nodes and update edges to point to new nodes
210 for(MSchedGraph::iterator N = GraphMap.begin(), NE = GraphMap.end();
210 for(MSchedGraph::iterator N = GraphMap.begin(), NE = GraphMap.end();
211211 N != NE; ++N) {
212212
213213 //Get the node we are dealing with
230230
231231 //Deconstructor, deletes all nodes in the graph
232232 MSchedGraph::~MSchedGraph () {
233 for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end();
233 for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end();
234234 I != E; ++I)
235235 delete I->second;
236236 }
237237
238238 //Print out graph
239239 void MSchedGraph::print(std::ostream &os) const {
240 for(MSchedGraph::const_iterator N = GraphMap.begin(), NE = GraphMap.end();
240 for(MSchedGraph::const_iterator N = GraphMap.begin(), NE = GraphMap.end();
241241 N != NE; ++N) {
242
242
243243 //Get the node we are dealing with
244244 MSchedGraphNode *node = &*(N->second);
245245
260260 int MSchedGraph::totalDelay() {
261261 int sum = 0;
262262
263 for(MSchedGraph::const_iterator N = GraphMap.begin(), NE = GraphMap.end();
263 for(MSchedGraph::const_iterator N = GraphMap.begin(), NE = GraphMap.end();
264264 N != NE; ++N) {
265
265
266266 //Get the node we are dealing with
267267 MSchedGraphNode *node = &*(N->second);
268268 sum += node->getLatency();
270270 return sum;
271271 }
272272 //Experimental code to add edges from the branch to all nodes dependent upon it.
273 void hasPath(MSchedGraphNode *node, std::set &visited,
273 void hasPath(MSchedGraphNode *node, std::set &visited,
274274 std::set &branches, MSchedGraphNode *startNode,
275275 std::set > &newEdges ) {
276276
297297 std::set branches;
298298 std::set nodes;
299299
300 for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end();
300 for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end();
301301 I != E; ++I) {
302302 if(I->second->isBranch())
303303 if(I->second->hasPredecessors())
307307 //See if there is a path first instruction to the branches, if so, add an
308308 //iteration dependence between that node and the branch
309309 std::set > newEdges;
310 for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end();
310 for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end();
311311 I != E; ++I) {
312312 std::set visited;
313313 hasPath((I->second), visited, branches, (I->second), newEdges);
346346 void MSchedGraph::buildNodesAndEdges(std::map &ignoreInstrs,
347347 DependenceAnalyzer &DA,
348348 std::map &machineTollvm) {
349
349
350350
351351 //Get Machine target information for calculating latency
352352 const TargetInstrInfo *MTI = Target.getInstrInfo();
359359 std::vector phiInstrs;
360360 unsigned index = 0;
361361
362 for(std::vector::iterator B = BBs.begin(),
362 for(std::vector::iterator B = BBs.begin(),
363363 BE = BBs.end(); B != BE; ++B) {
364
364
365365 const MachineBasicBlock *BB = *B;
366366
367367 //Loop over instructions in MBB and add nodes and edges
368 for (MachineBasicBlock::const_iterator MI = BB->begin(), e = BB->end();
368 for (MachineBasicBlock::const_iterator MI = BB->begin(), e = BB->end();
369369 MI != e; ++MI) {
370
370
371371 //Ignore indvar instructions
372372 if(ignoreInstrs.count(MI)) {
373373 ++index;
374374 continue;
375375 }
376
376
377377 //Get each instruction of machine basic block, get the delay
378378 //using the op code, create a new node for it, and add to the
379379 //graph.
380
380
381381 MachineOpCode opCode = MI->getOpcode();
382382 int delay;
383
383
384384 #if 0 // FIXME: LOOK INTO THIS
385385 //Check if subsequent instructions can be issued before
386386 //the result is ready, if so use min delay.
390390 #endif
391391 //Get delay
392392 delay = MTI->maxLatency(opCode);
393
393
394394 //Create new node for this machine instruction and add to the graph.
395395 //Create only if not a nop
396396 if(MTI->isNop(opCode))
397397 continue;
398
398
399399 //Sparc BE does not use PHI opcode, so assert on this case
400400 assert(opCode != TargetInstrInfo::PHI && "Did not expect PHI opcode");
401
401
402402 bool isBranch = false;
403
403
404404 //We want to flag the branch node to treat it special
405405 if(MTI->isBranch(opCode))
406406 isBranch = true;
407
407
408408 //Node is created and added to the graph automatically
409 MSchedGraphNode *node = new MSchedGraphNode(MI, this, index, delay,
409 MSchedGraphNode *node = new MSchedGraphNode(MI, this, index, delay,
410410 isBranch);
411
411
412412 DEBUG(std::cerr << "Created Node: " << *node << "\n");
413
413
414414 //Check OpCode to keep track of memory operations to add memory
415415 //dependencies later.
416416 if(MTI->isLoad(opCode) || MTI->isStore(opCode))
417417 memInstructions.push_back(node);
418
418
419419 //Loop over all operands, and put them into the register number to
420420 //graph node map for determining dependencies
421421 //If an operands is a use/def, we have an anti dependence to itself
422422 for(unsigned i=0; i < MI->getNumOperands(); ++i) {
423423 //Get Operand
424424 const MachineOperand &mOp = MI->getOperand(i);
425
425
426426 //Check if it has an allocated register
427427 if(mOp.hasAllocatedReg()) {
428428 int regNum = mOp.getReg();
429
429
430430 if(regNum != SparcV9::g0) {
431431 //Put into our map
432432 regNumtoNodeMap[regNum].push_back(std::make_pair(i, node));
433433 }
434434 continue;
435435 }
436
437
436
437
438438 //Add virtual registers dependencies
439439 //Check if any exist in the value map already and create dependencies
440440 //between them.
441 if(mOp.getType() == MachineOperand::MO_VirtualRegister
441 if(mOp.getType() == MachineOperand::MO_VirtualRegister
442442 || mOp.getType() == MachineOperand::MO_CCRegister) {
443
443
444444 //Make sure virtual register value is not null
445445 assert((mOp.getVRegValue() != NULL) && "Null value is defined");
446
446
447447 //Check if this is a read operation in a phi node, if so DO NOT PROCESS
448448 if(mOp.isUse() && (opCode == TargetInstrInfo::PHI)) {
449449 DEBUG(std::cerr << "Read Operation in a PHI node\n");
450450 continue;
451451 }
452
452
453453 if (const Value* srcI = mOp.getVRegValue()) {
454
454
455455 //Find value in the map
456456 std::map >::iterator V
457457 = valuetoNodeMap.find(srcI);
458
458
459459 //If there is something in the map already, add edges from
460460 //those instructions
461461 //to this one we are processing
462462 if(V != valuetoNodeMap.end()) {
463463 addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), phiInstrs);
464
464
465465 //Add to value map
466466 V->second.push_back(std::make_pair(i,node));
467467 }
474474 }
475475 ++index;
476476 }
477
477
478478 //Loop over LLVM BB, examine phi instructions, and add them to our
479479 //phiInstr list to process
480480 const BasicBlock *llvm_bb = BB->getBasicBlock();
481 for(BasicBlock::const_iterator I = llvm_bb->begin(), E = llvm_bb->end();
481 for(BasicBlock::const_iterator I = llvm_bb->begin(), E = llvm_bb->end();
482482 I != E; ++I) {
483483 if(const PHINode *PN = dyn_cast(I)) {
484484 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(PN);
489489 }
490490 }
491491 }
492
493 }
494
492
493 }
494
495495 addMemEdges(memInstructions, DA, machineTollvm);
496496 addMachRegEdges(regNumtoNodeMap);
497
497
498498 //Finally deal with PHI Nodes and Value*
499 for(std::vector::iterator I = phiInstrs.begin(),
499 for(std::vector::iterator I = phiInstrs.begin(),
500500 E = phiInstrs.end(); I != E; ++I) {
501
501
502502 //Get Node for this instruction
503503 std::map::iterator X;
504504 X = find(*I);
505
505
506506 if(X == GraphMap.end())
507507 continue;
508
508
509509 MSchedGraphNode *node = X->second;
510
510
511511 DEBUG(std::cerr << "Adding ite diff edges for node: " << *node << "\n");
512
512
513513 //Loop over operands for this instruction and add value edges
514514 for(unsigned i=0; i < (*I)->getNumOperands(); ++i) {
515515 //Get Operand
516516 const MachineOperand &mOp = (*I)->getOperand(i);
517 if((mOp.getType() == MachineOperand::MO_VirtualRegister
517 if((mOp.getType() == MachineOperand::MO_VirtualRegister
518518 || mOp.getType() == MachineOperand::MO_CCRegister) && mOp.isUse()) {
519
519
520520 //find the value in the map
521521 if (const Value* srcI = mOp.getVRegValue()) {
522
522
523523 //Find value in the map
524524 std::map >::iterator V
525525 = valuetoNodeMap.find(srcI);
526
526
527527 //If there is something in the map already, add edges from
528528 //those instructions
529529 //to this one we are processing
530530 if(V != valuetoNodeMap.end()) {
531 addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(),
531 addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(),
532532 phiInstrs, 1);
533533 }
534534 }
581581 //Loop over all machine registers in the map, and add dependencies
582582 //between the instructions that use it
583583 typedef std::map > regNodeMap;
584 for(regNodeMap::iterator I = regNumtoNodeMap.begin();
584 for(regNodeMap::iterator I = regNumtoNodeMap.begin();
585585 I != regNumtoNodeMap.end(); ++I) {
586586 //Get the register number
587587 int regNum = (*I).first;
608608
609609 //Look at all instructions after this in execution order
610610 for(unsigned j=i+1; j < Nodes.size(); ++j) {
611
611
612612 //Sink node is a write
613613 if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) {
614614 //Src only uses the register (read)
615615 if(srcIsUse)
616 srcNode->addOutEdge(Nodes[j].second,
616 srcNode->addOutEdge(Nodes[j].second,
617617 MSchedGraphEdge::MachineRegister,
618618 MSchedGraphEdge::AntiDep);
619
619
620620 else if(srcIsUseandDef) {
621 srcNode->addOutEdge(Nodes[j].second,
621 srcNode->addOutEdge(Nodes[j].second,
622622 MSchedGraphEdge::MachineRegister,
623623 MSchedGraphEdge::AntiDep);
624
625 srcNode->addOutEdge(Nodes[j].second,
624
625 srcNode->addOutEdge(Nodes[j].second,
626626 MSchedGraphEdge::MachineRegister,
627627 MSchedGraphEdge::OutputDep);
628628 }
629629 else
630 srcNode->addOutEdge(Nodes[j].second,
630 srcNode->addOutEdge(Nodes[j].second,
631631 MSchedGraphEdge::MachineRegister,
632632 MSchedGraphEdge::OutputDep);
633633 }
634634 //Dest node is a read
635635 else {
636636 if(!srcIsUse || srcIsUseandDef)
637 srcNode->addOutEdge(Nodes[j].second,
637 srcNode->addOutEdge(Nodes[j].second,
638638 MSchedGraphEdge::MachineRegister,
639639 MSchedGraphEdge::TrueDep);
640640 }
648648 if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) {
649649 //Src only uses the register (read)
650650 if(srcIsUse)
651 srcNode->addOutEdge(Nodes[j].second,
651 srcNode->addOutEdge(Nodes[j].second,
652652 MSchedGraphEdge::MachineRegister,
653653 MSchedGraphEdge::AntiDep, 1);
654654 else if(srcIsUseandDef) {
655 srcNode->addOutEdge(Nodes[j].second,
655 srcNode->addOutEdge(Nodes[j].second,
656656 MSchedGraphEdge::MachineRegister,
657657 MSchedGraphEdge::AntiDep, 1);
658
659 srcNode->addOutEdge(Nodes[j].second,
658
659 srcNode->addOutEdge(Nodes[j].second,
660660 MSchedGraphEdge::MachineRegister,
661661 MSchedGraphEdge::OutputDep, 1);
662662 }
663663 else
664 srcNode->addOutEdge(Nodes[j].second,
664 srcNode->addOutEdge(Nodes[j].second,
665665 MSchedGraphEdge::MachineRegister,
666666 MSchedGraphEdge::OutputDep, 1);
667667 }
668668 //Dest node is a read
669669 else {
670670 if(!srcIsUse || srcIsUseandDef)
671 srcNode->addOutEdge(Nodes[j].second,
671 srcNode->addOutEdge(Nodes[j].second,
672672 MSchedGraphEdge::MachineRegister,
673673 MSchedGraphEdge::TrueDep,1 );
674674 }
675
675
676676
677677 }
678678
684684
685685 //Add edges between all loads and stores
686686 //Can be less strict with alias analysis and data dependence analysis.
687 void MSchedGraph::addMemEdges(const std::vector& memInst,
688 DependenceAnalyzer &DA,
687 void MSchedGraph::addMemEdges(const std::vector& memInst,
688 DependenceAnalyzer &DA,
689689 std::map &machineTollvm) {
690690
691691 //Get Target machine instruction info
699699
700700 //Get the machine opCode to determine type of memory instruction
701701 MachineOpCode srcNodeOpCode = srcInst->getOpcode();
702
702
703703 //All instructions after this one in execution order have an
704704 //iteration delay of 0
705705 for(unsigned destIndex = 0; destIndex < memInst.size(); ++destIndex) {
712712
713713 DEBUG(std::cerr << "MInst1: " << *srcInst << "\n");
714714 DEBUG(std::cerr << "MInst2: " << *destInst << "\n");
715
715
716716 //Assuming instructions without corresponding llvm instructions
717717 //are from constant pools.
718718 if (!machineTollvm.count(srcInst) || !machineTollvm.count(destInst))
719719 continue;
720
720
721721 bool useDepAnalyzer = true;
722722
723723 //Some machine loads and stores are generated by casts, so be
724724 //conservative and always add deps
725725 Instruction *srcLLVM = machineTollvm[srcInst];
726726 Instruction *destLLVM = machineTollvm[destInst];
727 if(!isa(srcLLVM)
727 if(!isa(srcLLVM)
728728 && !isa(srcLLVM)) {
729729 if(isa(srcLLVM)) {
730730 if(isa(srcLLVM->getOperand(0)) || isa(srcLLVM->getOperand(1)))
732732 }
733733 useDepAnalyzer = false;
734734 }
735 if(!isa(destLLVM)
735 if(!isa(destLLVM)
736736 && !isa(destLLVM)) {
737737 if(isa(destLLVM)) {
738738 if(isa(destLLVM->getOperand(0)) || isa(destLLVM->getOperand(1)))
747747 if(destIndex < srcIndex)
748748 srcBeforeDest = false;
749749
750 DependenceResult dr = DA.getDependenceInfo(machineTollvm[srcInst],
751 machineTollvm[destInst],
750 DependenceResult dr = DA.getDependenceInfo(machineTollvm[srcInst],
751 machineTollvm[destInst],
752752 srcBeforeDest);
753
754 for(std::vector::iterator d = dr.dependences.begin(),
753
754 for(std::vector::iterator d = dr.dependences.begin(),
755755 de = dr.dependences.end(); d != de; ++d) {
756756 //Add edge from load to store
757 memInst[srcIndex]->addOutEdge(memInst[destIndex],
758 MSchedGraphEdge::MemoryDep,
757 memInst[srcIndex]->addOutEdge(memInst[destIndex],
758 MSchedGraphEdge::MemoryDep,
759759 d->getDepType(), d->getIteDiff());
760
760
761761 }
762762 }
763763 //Otherwise, we can not do any further analysis and must make a dependence
764764 else {
765
765
766766 //Get the machine opCode to determine type of memory instruction
767767 MachineOpCode destNodeOpCode = destInst->getOpcode();
768768
769769 //Get the Value* that we are reading from the load, always the first op
770770 const MachineOperand &mOp = srcInst->getOperand(0);
771771 const MachineOperand &mOp2 = destInst->getOperand(0);
772
772
773773 if(mOp.hasAllocatedReg())
774774 if(mOp.getReg() == SparcV9::g0)
775775 continue;
782782 if(TMI->isLoad(srcNodeOpCode)) {
783783
784784 if(TMI->isStore(destNodeOpCode))
785 memInst[srcIndex]->addOutEdge(memInst[destIndex],
786 MSchedGraphEdge::MemoryDep,
785 memInst[srcIndex]->addOutEdge(memInst[destIndex],
786 MSchedGraphEdge::MemoryDep,
787787 MSchedGraphEdge::AntiDep, 0);
788788 }
789789 else if(TMI->isStore(srcNodeOpCode)) {
790790 if(TMI->isStore(destNodeOpCode))
791 memInst[srcIndex]->addOutEdge(memInst[destIndex],
792 MSchedGraphEdge::MemoryDep,
791 memInst[srcIndex]->addOutEdge(memInst[destIndex],
792 MSchedGraphEdge::MemoryDep,
793793 MSchedGraphEdge::OutputDep, 0);
794794
795795 else
796 memInst[srcIndex]->addOutEdge(memInst[destIndex],
797 MSchedGraphEdge::MemoryDep,
796 memInst[srcIndex]->addOutEdge(memInst[destIndex],
797 MSchedGraphEdge::MemoryDep,
798798 MSchedGraphEdge::TrueDep, 0);
799799 }
800800 }
3535 //MSchedGraphSBNode constructor
3636 MSchedGraphSBNode::MSchedGraphSBNode(const MachineInstr* inst,
3737 MSchedGraphSB *graph, unsigned idx,
38 unsigned late, bool isBranch)
39 : Inst(inst), Parent(graph), index(idx), latency(late),
38 unsigned late, bool isBranch)
39 : Inst(inst), Parent(graph), index(idx), latency(late),
4040 isBranchInstr(isBranch) {
4141
4242 //Add to the graph
4949 MSchedGraphSB *graph, unsigned idx,
5050