llvm.org GIT mirror llvm / 9eb59ec
Eliminate tabs and trailing spaces. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22520 91177308-0d34-0410-b5e6-96231b3b80d8 Jeff Cohen 15 years ago
64 changed file(s) with 3973 addition(s) and 3973 deletion(s). Raw diff Collapse all Expand all
109109 inline Interval::succ_iterator succ_end(Interval *I) {
110110 return I->Successors.end();
111111 }
112
112
113113 /// pred_begin/pred_end - define methods so that Intervals may be used
114114 /// just like BasicBlocks can with the pred_* functions, and *::pred_iterator.
115115 ///
127127 static NodeType *getEntryNode(Interval *I) { return I; }
128128
129129 /// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
130 static inline ChildIteratorType child_begin(NodeType *N) {
130 static inline ChildIteratorType child_begin(NodeType *N) {
131131 return succ_begin(N);
132132 }
133133 static inline ChildIteratorType child_end(NodeType *N) {
159159 /// splitBasicBlock - This splits a basic block into two at the specified
160160 /// instruction. Note that all instructions BEFORE the specified iterator
161161 /// stay as part of the original basic block, an unconditional branch is added
162 /// to the original BB, and the rest of the instructions in the BB are moved
162 /// to the original BB, and the rest of the instructions in the BB are moved
163163 /// to the new BB, including the old terminator. The newly formed BasicBlock
164164 /// is returned. This function invalidates the specified iterator.
165165 ///
5454
5555 public:
5656 MachineRelocation(unsigned Offset, unsigned RelocationType, GlobalValue *GV,
57 intptr_t cst = 0, bool DoesntNeedFunctionStub = 0,
57 intptr_t cst = 0, bool DoesntNeedFunctionStub = 0,
5858 bool GOTrelative = 0)
5959 : OffsetTypeExternal(Offset + (RelocationType << 26)), ConstantVal(cst),
6060 GOTRelative(GOTrelative), isConstPool(0) {
174174 }
175175
176176 /// getGOTIndex - Once this has been resolved to an entry in the GOT,
177 /// this returns that index. The index is from the lowest address entry
177 /// this returns that index. The index is from the lowest address entry
178178 /// in the GOT.
179179 unsigned getGOTIndex() const {
180180 return Target.GOTIndex;
507507 assert(ResNo < Values.size() && "Illegal result number!");
508508 return Values[ResNo];
509509 }
510
510
511511 typedef std::vector::const_iterator value_iterator;
512512 value_iterator value_begin() const { return Values.begin(); }
513513 value_iterator value_end() const { return Values.end(); }
522522
523523 /// setAdjCallChain - This method should only be used by the legalizer.
524524 void setAdjCallChain(SDOperand N);
525
525
526526 protected:
527527 friend class SelectionDAG;
528528
448448 /* If using the C implementation of alloca, define if you know the
449449 direction of stack growth for your system; otherwise it will be
450450 automatically deduced at run-time.
451 STACK_DIRECTION > 0 => grows toward higher addresses
452 STACK_DIRECTION < 0 => grows toward lower addresses
453 STACK_DIRECTION = 0 => direction of growth unknown */
451 STACK_DIRECTION > 0 => grows toward higher addresses
452 STACK_DIRECTION < 0 => grows toward lower addresses
453 STACK_DIRECTION = 0 => direction of growth unknown */
454454 #undef STACK_DIRECTION
455455
456456 /* Define to 1 if the `S_IS*' macros in do not work properly. */
8080 //===----------------------------------------------------------------------===//
8181 //
8282 // Annotable - This class is used as a base class for all objects that would
83 // like to have annotation capability.
83 // like to have annotation capability.
8484 //
8585 // Annotable objects keep their annotation list sorted as annotations are
8686 // inserted and deleted. This is used to ensure that annotations with identical
733733
734734 virtual bool handleOccurrence(unsigned pos, const char *ArgName,
735735 const std::string &Arg) {
736 typename ParserClass::parser_data_type Val =
736 typename ParserClass::parser_data_type Val =
737737 typename ParserClass::parser_data_type();
738738 if (Parser.parse(*this, ArgName, Arg, Val))
739739 return true; // Parse error!
0 //===-- include/Support/DataTypes.h - Define fixed size types ---*- C++ -*-===//
1 //
1 //
22 // The LLVM Compiler Infrastructure
33 //
44 // This file was developed by the LLVM research group and is distributed under
55 // the University of Illinois Open Source License. See LICENSE.TXT for details.
6 //
6 //
77 //===----------------------------------------------------------------------===//
88 //
99 // This file contains definitions to figure out the size of _HOST_ data types.
0 //===-- Support/MutexGuard.h - Acquire/Release Mutex In Scope ---*- C++ -*-===//
1 //
1 //
22 // The LLVM Compiler Infrastructure
33 //
44 // This file was developed by the LLVM research group and is distributed under
55 // the University of Illinois Open Source License. See LICENSE.TXT for details.
6 //
6 //
77 //===----------------------------------------------------------------------===//
88 //
99 // This file defines a guard for a block of code that ensures a Mutex is locked
1717 #include
1818
1919 namespace llvm {
20 /// Instances of this class acquire a given Mutex Lock when constructed and
20 /// Instances of this class acquire a given Mutex Lock when constructed and
2121 /// hold that lock until destruction. The intention is to instantiate one of
2222 /// these on the stack at the top of some scope to be assured that C++
2323 /// destruction of the object will always release the Mutex and thus avoid
3333 /// holds - Returns true if this locker instance holds the specified lock.
3434 /// This is mostly used in assertions to validate that the correct mutex
3535 /// is held.
36 bool holds(const sys::Mutex& lock) const { return &M == &lock; }
36 bool holds(const sys::Mutex& lock) const { return &M == &lock; }
3737 };
3838 }
3939
4848
4949 /// Attempts to release the lock. If the lock is held by the current
5050 /// thread, the lock is released allowing other threads to acquire the
51 /// lock.
51 /// lock.
5252 /// @returns false if any kind of error occurs, true otherwise.
5353 /// @brief Unconditionally release the lock.
5454 bool release(void);
6060 /// available, true otherwise.
6161 /// @brief Try to acquire the lock.
6262 bool tryacquire();
63
63
6464 //@}
6565 /// @name Platform Dependent Data
6666 /// @{
7070 /// @}
7171 /// @name Do Not Implement
7272 /// @{
73 private:
73 private:
7474 Mutex(const Mutex & original);
7575 void operator=(const Mutex &);
7676 /// @}
2626 /// in the operating system's filesystem and provides various basic operations
2727 /// on it. Note that this class only represents the name of a path to a file
2828 /// or directory which may or may not be valid for a given machine's file
29 /// system. The class is patterned after the java.io.File class with various
30 /// extensions and several omissions (not relevant to LLVM). A Path object
31 /// ensures that the path it encapsulates is syntactically valid for the
32 /// operating system it is running on but does not ensure correctness for
33 /// any particular file system. That is, a syntactically valid path might
29 /// system. The class is patterned after the java.io.File class with various
30 /// extensions and several omissions (not relevant to LLVM). A Path object
31 /// ensures that the path it encapsulates is syntactically valid for the
32 /// operating system it is running on but does not ensure correctness for
33 /// any particular file system. That is, a syntactically valid path might
3434 /// specify path components that do not exist in the file system and using
3535 /// such a Path to act on the file system could produce errors. There is one
36 /// invalid Path value which is permitted: the empty path. The class should
37 /// never allow a syntactically invalid non-empty path name to be assigned.
36 /// invalid Path value which is permitted: the empty path. The class should
37 /// never allow a syntactically invalid non-empty path name to be assigned.
3838 /// Empty paths are required in order to indicate an error result in some
39 /// situations. If the path is empty, the isValid operation will return
40 /// false. All operations will fail if isValid is false. Operations that
39 /// situations. If the path is empty, the isValid operation will return
40 /// false. All operations will fail if isValid is false. Operations that
4141 /// change the path will either return false if it would cause a syntactically
42 /// invalid path name (in which case the Path object is left unchanged) or
42 /// invalid path name (in which case the Path object is left unchanged) or
4343 /// throw an std::string exception indicating the error. The methods are
4444 /// grouped into four basic categories: Path Accessors (provide information
4545 /// about the path without accessing disk), Disk Accessors (provide
322322 bool isDynamicLibrary() const;
323323
324324 /// This function determines if the path name references an existing file
325 /// or directory in the file system.
326 /// @returns true if the pathname references an existing file or
325 /// or directory in the file system.
326 /// @returns true if the pathname references an existing file or
327327 /// directory.
328328 /// @brief Determines if the path is a file or directory in
329329 /// the file system.
330330 bool exists() const;
331331
332332 /// This function determines if the path name references a readable file
333 /// or directory in the file system. This function checks for
334 /// the existence and readability (by the current program) of the file
333 /// or directory in the file system. This function checks for
334 /// the existence and readability (by the current program) of the file
335335 /// or directory.
336336 /// @returns true if the pathname references a readable file.
337337 /// @brief Determines if the path is a readable file or directory
339339 bool canRead() const;
340340
341341 /// This function determines if the path name references a writable file
342 /// or directory in the file system. This function checks for the
343 /// existence and writability (by the current program) of the file or
342 /// or directory in the file system. This function checks for the
343 /// existence and writability (by the current program) of the file or
344344 /// directory.
345345 /// @returns true if the pathname references a writable file.
346346 /// @brief Determines if the path is a writable file or directory
348348 bool canWrite() const;
349349
350350 /// This function determines if the path name references an executable
351 /// file in the file system. This function checks for the existence and
351 /// file in the file system. This function checks for the existence and
352352 /// executability (by the current program) of the file.
353353 /// @returns true if the pathname references an executable file.
354354 /// @brief Determines if the path is an executable file in the file
399399
400400 /// This method sets the Path object to \p unverified_path. This can fail
401401 /// if the \p unverified_path does not pass the syntactic checks of the
402 /// isValid() method. If verification fails, the Path object remains
402 /// isValid() method. If verification fails, the Path object remains
403403 /// unchanged and false is returned. Otherwise true is returned and the
404404 /// Path object takes on the path value of \p unverified_path
405405 /// @returns true if the path was set, false otherwise.
416416
417417 /// The \p component is added to the end of the Path if it is a legal
418418 /// name for the operating system. A directory separator will be added if
419 /// needed.
419 /// needed.
420420 /// @returns false if the path component could not be added.
421421 /// @brief Appends one path component to the Path.
422422 bool appendComponent( const std::string& component );
468468 /// @brief Make the file readable;
469469 void makeExecutableOnDisk();
470470
471 /// This method allows the last modified time stamp and permission bits
471 /// This method allows the last modified time stamp and permission bits
472472 /// to be set on the disk object referenced by the Path.
473473 /// @throws std::string if an error occurs.
474474 /// @returns true
479479 /// same name as the Path object. The \p create_parents parameter controls
480480 /// whether intermediate directories are created or not. if \p
481481 /// create_parents is true, then an attempt will be made to create all
482 /// intermediate directories, as needed. If \p create_parents is false,
483 /// then only the final directory component of the Path name will be
482 /// intermediate directories, as needed. If \p create_parents is false,
483 /// then only the final directory component of the Path name will be
484484 /// created. The created directory will have no entries.
485485 /// @returns false if the Path does not reference a directory, true
486486 /// otherwise.
506506 /// file is created. Note that this will both change the Path object
507507 /// *and* create the corresponding file. This function will ensure that
508508 /// the newly generated temporary file name is unique in the file system.
509 /// @param reuse_current When set to true, this parameter indicates that
509 /// @param reuse_current When set to true, this parameter indicates that
510510 /// if the current file name does not exist then it will be used without
511511 /// modification.
512512 /// @returns true if successful, false if the file couldn't be created.
516516 bool createTemporaryFileOnDisk(bool reuse_current = false);
517517
518518 /// This method renames the file referenced by \p this as \p newName. The
519 /// file referenced by \p this must exist. The file referenced by
519 /// file referenced by \p this must exist. The file referenced by
520520 /// \p newName does not need to exist.
521521 /// @returns true
522522 /// @throws std::string if there is an file system error.
523523 /// @brief Rename one file as another.
524524 bool renamePathOnDisk(const Path& newName);
525525
526 /// This method attempts to destroy the file or directory named by the
526 /// This method attempts to destroy the file or directory named by the
527527 /// last component of the Path. If the Path refers to a directory and the
528 /// \p destroy_contents is false, an attempt will be made to remove just
529 /// the directory (the final Path component). If \p destroy_contents is
530 /// true, an attempt will be made to remove the entire contents of the
528 /// \p destroy_contents is false, an attempt will be made to remove just
529 /// the directory (the final Path component). If \p destroy_contents is
530 /// true, an attempt will be made to remove the entire contents of the
531531 /// directory, recursively. If the Path refers to a file, the
532532 /// \p destroy_contents parameter is ignored.
533533 /// @param destroy_contents Indicates whether the contents of a destroyed
6666 /// Not all operating systems support this feature. Where it is not
6767 /// supported, the function should return 65536 as the value.
6868 static int GetCurrentUserId();
69
69
7070 /// This static function will return the process' current group id number.
7171 /// Not all operating systems support this feature. Where it is not
7272 /// supported, the function should return 65536 as the value.
207207
208208 /// This function returns true if the target allows unaligned stores. This is
209209 /// used in situations where an array copy/move/set is converted to a sequence
210 /// of store operations. It ensures that such replacements don't generate
211 /// code that causes an alignment error (trap) on the target machine.
210 /// of store operations. It ensures that such replacements don't generate
211 /// code that causes an alignment error (trap) on the target machine.
212212 /// @brief Determine if the target supports unaligned stores.
213213 bool allowsUnalignedStores() const { return allowUnalignedStores; }
214214
398398 /// should assume that the memset will be done using as many of the largest
399399 /// store operations first, followed by smaller ones, if necessary, per
400400 /// alignment restrictions. For example, storing 9 bytes on a 32-bit machine
401 /// with 16-bit alignment would result in four 2-byte stores and one 1-byte
401 /// with 16-bit alignment would result in four 2-byte stores and one 1-byte
402402 /// store. This only applies to setting a constant array of a constant size.
403403 /// @brief Specify maximum number of store instructions per memset call.
404404 unsigned maxStoresPerMemSet;
420420 /// must set this value based on the cost threshold for that target. Targets
421421 /// should assume that the memmove will be done using as many of the largest
422422 /// store operations first, followed by smaller ones, if necessary, per
423 /// alignment restrictions. For example, moving 9 bytes on a 32-bit machine
424 /// with 8-bit alignment would result in nine 1-byte stores. This only
423 /// alignment restrictions. For example, moving 9 bytes on a 32-bit machine
424 /// with 8-bit alignment would result in nine 1-byte stores. This only
425425 /// applies to copying a constant array of constant size.
426426 /// @brief Specify maximum bytes of store instructions per memmove call.
427427 unsigned maxStoresPerMemMove;
428428
429429 /// This field specifies whether the target machine permits unaligned stores.
430 /// This is used to determine the size of store operations for copying
430 /// This is used to determine the size of store operations for copying
431431 /// small arrays and other similar tasks.
432432 /// @brief Indicate whether the target machine permits unaligned stores.
433433 bool allowUnalignedStores;
101101 virtual const TargetFrameInfo *getFrameInfo() const { return 0; }
102102 const TargetData &getTargetData() const { return DataLayout; }
103103
104 /// getSubtarget - This method returns a pointer to the specified type of
104 /// getSubtarget - This method returns a pointer to the specified type of
105105 /// TargetSubtarget. In debug builds, it verifies that the object being
106106 /// returned is of the correct type.
107107 template STC *getSubtarget() const {
2727 #ifndef LTDL_H
2828 #define LTDL_H 1
2929
30 #include /* for size_t declaration */
30 #include /* for size_t declaration */
3131
3232
3333 /* --- MACROS FOR PORTABILITY --- */
3434
3535
3636 /* Saves on those hard to debug '\0' typos.... */
37 #define LT_EOS_CHAR '\0'
37 #define LT_EOS_CHAR '\0'
3838
3939 /* LTDL_BEGIN_C_DECLS should be used at the beginning of your declarations,
4040 so that C++ compilers don't mangle their names. Use LTDL_END_C_DECLS at
4141 the end of C declarations. */
4242 #ifdef __cplusplus
43 # define LT_BEGIN_C_DECLS extern "C" {
44 # define LT_END_C_DECLS }
43 # define LT_BEGIN_C_DECLS extern "C" {
44 # define LT_END_C_DECLS }
4545 #else
46 # define LT_BEGIN_C_DECLS /* empty */
47 # define LT_END_C_DECLS /* empty */
46 # define LT_BEGIN_C_DECLS /* empty */
47 # define LT_END_C_DECLS /* empty */
4848 #endif
4949
5050 LT_BEGIN_C_DECLS
5454 that don't understand ANSI C prototypes still work, and ANSI C
5555 compilers can issue warnings about type mismatches. */
5656 #if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32) || defined(__cplusplus)
57 # define LT_PARAMS(protos) protos
58 # define lt_ptr void*
57 # define LT_PARAMS(protos) protos
58 # define lt_ptr void*
5959 #else
60 # define LT_PARAMS(protos) ()
61 # define lt_ptr char*
60 # define LT_PARAMS(protos) ()
61 # define lt_ptr char*
6262 #endif
6363
6464 /* LT_STMT_START/END are used to create macros which expand to a
7979 /* LT_CONC creates a new concatenated symbol for the compiler
8080 in a portable way. */
8181 #if defined(__STDC__) || defined(__cplusplus) || defined(_MSC_VER)
82 # define LT_CONC(s,t) s##t
82 # define LT_CONC(s,t) s##t
8383 #else
84 # define LT_CONC(s,t) s/**/t
84 # define LT_CONC(s,t) s/**/t
8585 #endif
8686
8787 /* LT_STRLEN can be used safely on NULL pointers. */
88 #define LT_STRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0)
88 #define LT_STRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0)
8989
9090
9191
115115 # ifndef __CYGWIN__
116116 /* LT_DIRSEP_CHAR is accepted *in addition* to '/' as a directory
117117 separator when it is set. */
118 # define LT_DIRSEP_CHAR '\\'
119 # define LT_PATHSEP_CHAR ';'
118 # define LT_DIRSEP_CHAR '\\'
119 # define LT_PATHSEP_CHAR ';'
120120 # endif
121121 #endif
122122 #ifndef LT_PATHSEP_CHAR
123 # define LT_PATHSEP_CHAR ':'
123 # define LT_PATHSEP_CHAR ':'
124124 #endif
125125
126126 /* DLL building support on win32 hosts; mostly to workaround their
127127 ridiculous implementation of data symbol exporting. */
128128 #ifndef LT_SCOPE
129129 # ifdef __WINDOWS__
130 # ifdef DLL_EXPORT /* defined by libtool (if required) */
131 # define LT_SCOPE __declspec(dllexport)
130 # ifdef DLL_EXPORT /* defined by libtool (if required) */
131 # define LT_SCOPE __declspec(dllexport)
132132 # endif
133 # ifdef LIBLTDL_DLL_IMPORT /* define if linking with this dll */
134 # define LT_SCOPE extern __declspec(dllimport)
133 # ifdef LIBLTDL_DLL_IMPORT /* define if linking with this dll */
134 # define LT_SCOPE extern __declspec(dllimport)
135135 # endif
136136 # endif
137 # ifndef LT_SCOPE /* static linking or !__WINDOWS__ */
138 # define LT_SCOPE extern
137 # ifndef LT_SCOPE /* static linking or !__WINDOWS__ */
138 # define LT_SCOPE extern
139139 # endif
140140 #endif
141141
149149 /* --- DYNAMIC MODULE LOADING API --- */
150150
151151
152 typedef struct lt_dlhandle_struct *lt_dlhandle; /* A loaded module. */
152 typedef struct lt_dlhandle_struct *lt_dlhandle; /* A loaded module. */
153153
154154 /* Initialisation and finalisation functions for libltdl. */
155 LT_SCOPE int lt_dlinit LT_PARAMS((void));
156 LT_SCOPE int lt_dlexit LT_PARAMS((void));
155 LT_SCOPE int lt_dlinit LT_PARAMS((void));
156 LT_SCOPE int lt_dlexit LT_PARAMS((void));
157157
158158 /* Module search path manipulation. */
159 LT_SCOPE int lt_dladdsearchdir LT_PARAMS((const char *search_dir));
160 LT_SCOPE int lt_dlinsertsearchdir LT_PARAMS((const char *before,
161 const char *search_dir));
162 LT_SCOPE int lt_dlsetsearchpath LT_PARAMS((const char *search_path));
163 LT_SCOPE const char *lt_dlgetsearchpath LT_PARAMS((void));
164 LT_SCOPE int lt_dlforeachfile LT_PARAMS((
165 const char *search_path,
166 int (*func) (const char *filename, lt_ptr data),
167 lt_ptr data));
159 LT_SCOPE int lt_dladdsearchdir LT_PARAMS((const char *search_dir));
160 LT_SCOPE int lt_dlinsertsearchdir LT_PARAMS((const char *before,
161 const char *search_dir));
162 LT_SCOPE int lt_dlsetsearchpath LT_PARAMS((const char *search_path));
163 LT_SCOPE const char *lt_dlgetsearchpath LT_PARAMS((void));
164 LT_SCOPE int lt_dlforeachfile LT_PARAMS((
165 const char *search_path,
166 int (*func) (const char *filename, lt_ptr data),
167 lt_ptr data));
168168
169169 /* Portable libltdl versions of the system dlopen() API. */
170 LT_SCOPE lt_dlhandle lt_dlopen LT_PARAMS((const char *filename));
171 LT_SCOPE lt_dlhandle lt_dlopenext LT_PARAMS((const char *filename));
172 LT_SCOPE lt_ptr lt_dlsym LT_PARAMS((lt_dlhandle handle,
173 const char *name));
174 LT_SCOPE const char *lt_dlerror LT_PARAMS((void));
175 LT_SCOPE int lt_dlclose LT_PARAMS((lt_dlhandle handle));
170 LT_SCOPE lt_dlhandle lt_dlopen LT_PARAMS((const char *filename));
171 LT_SCOPE lt_dlhandle lt_dlopenext LT_PARAMS((const char *filename));
172 LT_SCOPE lt_ptr lt_dlsym LT_PARAMS((lt_dlhandle handle,
173 const char *name));
174 LT_SCOPE const char *lt_dlerror LT_PARAMS((void));
175 LT_SCOPE int lt_dlclose LT_PARAMS((lt_dlhandle handle));
176176
177177 /* Module residency management. */
178 LT_SCOPE int lt_dlmakeresident LT_PARAMS((lt_dlhandle handle));
179 LT_SCOPE int lt_dlisresident LT_PARAMS((lt_dlhandle handle));
178 LT_SCOPE int lt_dlmakeresident LT_PARAMS((lt_dlhandle handle));
179 LT_SCOPE int lt_dlisresident LT_PARAMS((lt_dlhandle handle));
180180
181181
182182
184184 /* --- MUTEX LOCKING --- */
185185
186186
187 typedef void lt_dlmutex_lock LT_PARAMS((void));
188 typedef void lt_dlmutex_unlock LT_PARAMS((void));
189 typedef void lt_dlmutex_seterror LT_PARAMS((const char *errmsg));
190 typedef const char *lt_dlmutex_geterror LT_PARAMS((void));
191
192 LT_SCOPE int lt_dlmutex_register LT_PARAMS((lt_dlmutex_lock *lock,
193 lt_dlmutex_unlock *unlock,
194 lt_dlmutex_seterror *seterror,
195 lt_dlmutex_geterror *geterror));
187 typedef void lt_dlmutex_lock LT_PARAMS((void));
188 typedef void lt_dlmutex_unlock LT_PARAMS((void));
189 typedef void lt_dlmutex_seterror LT_PARAMS((const char *errmsg));
190 typedef const char *lt_dlmutex_geterror LT_PARAMS((void));
191
192 LT_SCOPE int lt_dlmutex_register LT_PARAMS((lt_dlmutex_lock *lock,
193 lt_dlmutex_unlock *unlock,
194 lt_dlmutex_seterror *seterror,
195 lt_dlmutex_geterror *geterror));
196196
197197
198198
205205 libltdl relies on a featureful realloc, but if you are sure yours
206206 has the right semantics then you can assign it directly. Generally,
207207 it is safe to assign just a malloc() and a free() function. */
208 LT_SCOPE lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size));
209 LT_SCOPE lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size));
210 LT_SCOPE void (*lt_dlfree) LT_PARAMS((lt_ptr ptr));
208 LT_SCOPE lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size));
209 LT_SCOPE lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size));
210 LT_SCOPE void (*lt_dlfree) LT_PARAMS((lt_ptr ptr));
211211
212212
213213
222222 lt_ptr address;
223223 } lt_dlsymlist;
224224
225 LT_SCOPE int lt_dlpreload LT_PARAMS((const lt_dlsymlist *preloaded));
226 LT_SCOPE int lt_dlpreload_default
227 LT_PARAMS((const lt_dlsymlist *preloaded));
228
229 #define LTDL_SET_PRELOADED_SYMBOLS() LT_STMT_START{ \
230 extern const lt_dlsymlist lt_preloaded_symbols[]; \
231 lt_dlpreload_default(lt_preloaded_symbols); \
232 }LT_STMT_END
225 LT_SCOPE int lt_dlpreload LT_PARAMS((const lt_dlsymlist *preloaded));
226 LT_SCOPE int lt_dlpreload_default
227 LT_PARAMS((const lt_dlsymlist *preloaded));
228
229 #define LTDL_SET_PRELOADED_SYMBOLS() LT_STMT_START{ \
230 extern const lt_dlsymlist lt_preloaded_symbols[]; \
231 lt_dlpreload_default(lt_preloaded_symbols); \
232 }LT_STMT_END
233233
234234
235235
238238
239239
240240 /* Read only information pertaining to a loaded module. */
241 typedef struct {
242 char *filename; /* file name */
243 char *name; /* module name */
244 int ref_count; /* number of times lt_dlopened minus
245 number of times lt_dlclosed. */
241 typedef struct {
242 char *filename; /* file name */
243 char *name; /* module name */
244 int ref_count; /* number of times lt_dlopened minus
245 number of times lt_dlclosed. */
246246 } lt_dlinfo;
247247
248 LT_SCOPE const lt_dlinfo *lt_dlgetinfo LT_PARAMS((lt_dlhandle handle));
249 LT_SCOPE lt_dlhandle lt_dlhandle_next LT_PARAMS((lt_dlhandle place));
250 LT_SCOPE int lt_dlforeach LT_PARAMS((
251 int (*func) (lt_dlhandle handle, lt_ptr data),
252 lt_ptr data));
248 LT_SCOPE const lt_dlinfo *lt_dlgetinfo LT_PARAMS((lt_dlhandle handle));
249 LT_SCOPE lt_dlhandle lt_dlhandle_next LT_PARAMS((lt_dlhandle place));
250 LT_SCOPE int lt_dlforeach LT_PARAMS((
251 int (*func) (lt_dlhandle handle, lt_ptr data),
252 lt_ptr data));
253253
254254 /* Associating user data with loaded modules. */
255255 typedef unsigned lt_dlcaller_id;
256256
257 LT_SCOPE lt_dlcaller_id lt_dlcaller_register LT_PARAMS((void));
258 LT_SCOPE lt_ptr lt_dlcaller_set_data LT_PARAMS((lt_dlcaller_id key,
259 lt_dlhandle handle,
260 lt_ptr data));
261 LT_SCOPE lt_ptr lt_dlcaller_get_data LT_PARAMS((lt_dlcaller_id key,
262 lt_dlhandle handle));
257 LT_SCOPE lt_dlcaller_id lt_dlcaller_register LT_PARAMS((void));
258 LT_SCOPE lt_ptr lt_dlcaller_set_data LT_PARAMS((lt_dlcaller_id key,
259 lt_dlhandle handle,
260 lt_ptr data));
261 LT_SCOPE lt_ptr lt_dlcaller_get_data LT_PARAMS((lt_dlcaller_id key,
262 lt_dlhandle handle));
263263
264264
265265
266266 /* --- USER MODULE LOADER API --- */
267267
268268
269 typedef struct lt_dlloader lt_dlloader;
270 typedef lt_ptr lt_user_data;
271 typedef lt_ptr lt_module;
269 typedef struct lt_dlloader lt_dlloader;
270 typedef lt_ptr lt_user_data;
271 typedef lt_ptr lt_module;
272272
273273 /* Function pointer types for creating user defined module loaders. */
274 typedef lt_module lt_module_open LT_PARAMS((lt_user_data loader_data,
275 const char *filename));
276 typedef int lt_module_close LT_PARAMS((lt_user_data loader_data,
277 lt_module handle));
278 typedef lt_ptr lt_find_sym LT_PARAMS((lt_user_data loader_data,
279 lt_module handle,
280 const char *symbol));
281 typedef int lt_dlloader_exit LT_PARAMS((lt_user_data loader_data));
274 typedef lt_module lt_module_open LT_PARAMS((lt_user_data loader_data,
275 const char *filename));
276 typedef int lt_module_close LT_PARAMS((lt_user_data loader_data,
277 lt_module handle));
278 typedef lt_ptr lt_find_sym LT_PARAMS((lt_user_data loader_data,
279 lt_module handle,
280 const char *symbol));
281 typedef int lt_dlloader_exit LT_PARAMS((lt_user_data loader_data));
282282
283283 struct lt_user_dlloader {
284 const char *sym_prefix;
284 const char *sym_prefix;
285285 lt_module_open *module_open;
286286 lt_module_close *module_close;
287 lt_find_sym *find_sym;
287 lt_find_sym *find_sym;
288288 lt_dlloader_exit *dlloader_exit;
289 lt_user_data dlloader_data;
289 lt_user_data dlloader_data;
290290 };
291291
292 LT_SCOPE lt_dlloader *lt_dlloader_next LT_PARAMS((lt_dlloader *place));
293 LT_SCOPE lt_dlloader *lt_dlloader_find LT_PARAMS((
294 const char *loader_name));
295 LT_SCOPE const char *lt_dlloader_name LT_PARAMS((lt_dlloader *place));
296 LT_SCOPE lt_user_data *lt_dlloader_data LT_PARAMS((lt_dlloader *place));
297 LT_SCOPE int lt_dlloader_add LT_PARAMS((lt_dlloader *place,
298 const struct lt_user_dlloader *dlloader,
299 const char *loader_name));
300 LT_SCOPE int lt_dlloader_remove LT_PARAMS((
301 const char *loader_name));
292 LT_SCOPE lt_dlloader *lt_dlloader_next LT_PARAMS((lt_dlloader *place));
293 LT_SCOPE lt_dlloader *lt_dlloader_find LT_PARAMS((
294 const char *loader_name));
295 LT_SCOPE const char *lt_dlloader_name LT_PARAMS((lt_dlloader *place));
296 LT_SCOPE lt_user_data *lt_dlloader_data LT_PARAMS((lt_dlloader *place));
297 LT_SCOPE int lt_dlloader_add LT_PARAMS((lt_dlloader *place,
298 const struct lt_user_dlloader *dlloader,
299 const char *loader_name));
300 LT_SCOPE int lt_dlloader_remove LT_PARAMS((
301 const char *loader_name));
302302
303303
304304
309309 this way allows us to expand the macro in different contexts with
310310 confidence that the enumeration of symbolic names will map correctly
311311 onto the table of error strings. */
312 #define lt_dlerror_table \
313 LT_ERROR(UNKNOWN, "unknown error") \
314 LT_ERROR(DLOPEN_NOT_SUPPORTED, "dlopen support not available") \
315 LT_ERROR(INVALID_LOADER, "invalid loader") \
316 LT_ERROR(INIT_LOADER, "loader initialization failed") \
317 LT_ERROR(REMOVE_LOADER, "loader removal failed") \
318 LT_ERROR(FILE_NOT_FOUND, "file not found") \
319 LT_ERROR(DEPLIB_NOT_FOUND, "dependency library not found") \
320 LT_ERROR(NO_SYMBOLS, "no symbols defined") \
321 LT_ERROR(CANNOT_OPEN, "can't open the module") \
322 LT_ERROR(CANNOT_CLOSE, "can't close the module") \
323 LT_ERROR(SYMBOL_NOT_FOUND, "symbol not found") \
324 LT_ERROR(NO_MEMORY, "not enough memory") \
325 LT_ERROR(INVALID_HANDLE, "invalid module handle") \
326 LT_ERROR(BUFFER_OVERFLOW, "internal buffer overflow") \
327 LT_ERROR(INVALID_ERRORCODE, "invalid errorcode") \
328 LT_ERROR(SHUTDOWN, "library already shutdown") \
329 LT_ERROR(CLOSE_RESIDENT_MODULE, "can't close resident module") \
312 #define lt_dlerror_table \
313 LT_ERROR(UNKNOWN, "unknown error") \
314 LT_ERROR(DLOPEN_NOT_SUPPORTED, "dlopen support not available") \
315 LT_ERROR(INVALID_LOADER, "invalid loader") \
316 LT_ERROR(INIT_LOADER, "loader initialization failed") \
317 LT_ERROR(REMOVE_LOADER, "loader removal failed") \
318 LT_ERROR(FILE_NOT_FOUND, "file not found") \
319 LT_ERROR(DEPLIB_NOT_FOUND, "dependency library not found") \
320 LT_ERROR(NO_SYMBOLS, "no symbols defined") \
321 LT_ERROR(CANNOT_OPEN, "can't open the module") \
322 LT_ERROR(CANNOT_CLOSE, "can't close the module") \
323 LT_ERROR(SYMBOL_NOT_FOUND, "symbol not found") \
324 LT_ERROR(NO_MEMORY, "not enough memory") \
325 LT_ERROR(INVALID_HANDLE, "invalid module handle") \
326 LT_ERROR(BUFFER_OVERFLOW, "internal buffer overflow") \
327 LT_ERROR(INVALID_ERRORCODE, "invalid errorcode") \
328 LT_ERROR(SHUTDOWN, "library already shutdown") \
329 LT_ERROR(CLOSE_RESIDENT_MODULE, "can't close resident module") \
330330 LT_ERROR(INVALID_MUTEX_ARGS, "invalid mutex handler registration") \
331 LT_ERROR(INVALID_POSITION, "invalid search path insert position")
331 LT_ERROR(INVALID_POSITION, "invalid search path insert position")
332332
333333 /* Enumerate the symbolic error names. */
334334 enum {
335 #define LT_ERROR(name, diagnostic) LT_CONC(LT_ERROR_, name),
336 lt_dlerror_table
335 #define LT_ERROR(name, diagnostic) LT_CONC(LT_ERROR_, name),
336 lt_dlerror_table
337337 #undef LT_ERROR
338338
339 LT_ERROR_MAX
339 LT_ERROR_MAX
340340 };
341341
342342 /* These functions are only useful from inside custom module loaders. */
343 LT_SCOPE int lt_dladderror LT_PARAMS((const char *diagnostic));
344 LT_SCOPE int lt_dlseterror LT_PARAMS((int errorcode));
343 LT_SCOPE int lt_dladderror LT_PARAMS((const char *diagnostic));
344 LT_SCOPE int lt_dlseterror LT_PARAMS((int errorcode));
345345
346346
347347
350350
351351
352352 #ifdef LT_NON_POSIX_NAMESPACE
353 # define lt_ptr_t lt_ptr
354 # define lt_module_t lt_module
355 # define lt_module_open_t lt_module_open
356 # define lt_module_close_t lt_module_close
357 # define lt_find_sym_t lt_find_sym
358 # define lt_dlloader_exit_t lt_dlloader_exit
359 # define lt_dlloader_t lt_dlloader
360 # define lt_dlloader_data_t lt_user_data
353 # define lt_ptr_t lt_ptr
354 # define lt_module_t lt_module
355 # define lt_module_open_t lt_module_open
356 # define lt_module_close_t lt_module_close
357 # define lt_find_sym_t lt_find_sym
358 # define lt_dlloader_exit_t lt_dlloader_exit
359 # define lt_dlloader_t lt_dlloader
360 # define lt_dlloader_data_t lt_user_data
361361 #endif
362362
363363 LT_END_C_DECLS
1515
1616 #include "llvm/CodeGen/MachineRelocation.h"
1717
18 // Hack to rid us of a PPC pre-processor symbol which is erroneously
18 // Hack to rid us of a PPC pre-processor symbol which is erroneously
1919 // defined in a PowerPC header file (bug in Linux/PPC)
2020 #ifdef PPC
2121 #undef PPC
6161 };
6262
6363 static void writePrologue (std::ostream &Out, const std::string &comment,
64 const std::string &symName) {
64 const std::string &symName) {
6565 // Prologue:
6666 // Output a comment describing the object.
6767 Out << "!" << comment << "\n";
7979 Out << ".end_" << symName << ":\n";
8080 // Output size directive giving the size of the object:
8181 Out << "\t.size " << symName << ", .end_" << symName << "-" << symName
82 << "\n";
82 << "\n";
8383 }
8484
8585 // SparcV9BytecodeWriter - Write bytecode out to a stream that is sparc'ified
6767 private:
6868 friend class InstrSchedule;
6969
70 inline void addInstr(const SchedGraphNode* node, unsigned int slotNum) {
70 inline void addInstr(const SchedGraphNode* node, unsigned int slotNum) {
7171 assert(slotNum < group.size());
7272 group[slotNum] = node;
7373 }
7474
75 /*ctor*/ InstrGroup(unsigned int nslots)
75 /*ctor*/ InstrGroup(unsigned int nslots)
7676 : group(nslots, NULL) {}
7777
78 /*ctor*/ InstrGroup(); // disable: DO NOT IMPLEMENT
78 /*ctor*/ InstrGroup(); // disable: DO NOT IMPLEMENT
7979
8080 private:
8181 std::vector group;
9999 typedef ScheduleIterator<_NodeType> _Self;
100100
101101 /*ctor*/ inline ScheduleIterator(const InstrSchedule& _schedule,
102 unsigned _cycleNum,
103 unsigned _slotNum)
102 unsigned _cycleNum,
103 unsigned _slotNum)
104104 : cycleNum(_cycleNum), slotNum(_slotNum), S(_schedule) {
105105 skipToNextInstr();
106106 }
117117 inline _NodeType* operator*() const;
118118 inline _NodeType* operator->() const { return operator*(); }
119119
120 _Self& operator++(); // Preincrement
121 inline _Self operator++(int) { // Postincrement
120 _Self& operator++(); // Preincrement
121 inline _Self operator++(int) { // Postincrement
122122 _Self tmp(*this); ++*this; return tmp;
123123 }
124124
127127
128128 private:
129129 inline _Self& operator=(const _Self& x); // DISABLE -- DO NOT IMPLEMENT
130 void skipToNextInstr();
130 void skipToNextInstr();
131131 };
132132
133133
140140 class InstrSchedule {
141141 const unsigned int nslots;
142142 unsigned int numInstr;
143 std::vector groups; // indexed by cycle number
144 std::vector<CycleCount_t> startTime; // indexed by node id
143 std::vector<InstrGroup*> groups; // indexed by cycle number
144 std::vector startTime; // indexed by node id
145145
146146 InstrSchedule(InstrSchedule&); // DO NOT IMPLEMENT
147147 void operator=(InstrSchedule&); // DO NOT IMPLEMENT
156156 const_iterator end() const { return const_iterator::end(*this); }
157157
158158 public: // constructors and destructor
159 /*ctor*/ InstrSchedule (unsigned int _nslots,
160 unsigned int _numNodes);
161 /*dtor*/ ~InstrSchedule ();
159 /*ctor*/ InstrSchedule (unsigned int _nslots,
160 unsigned int _numNodes);
161 /*dtor*/ ~InstrSchedule ();
162162
163163 public: // accessor functions to query chosen schedule
164 const SchedGraphNode* getInstr (unsigned int slotNum,
165 CycleCount_t c) {
164 const SchedGraphNode* getInstr (unsigned int slotNum,
165 CycleCount_t c) {
166166 const InstrGroup* igroup = this->getIGroup(c);
167167 return (igroup == NULL)? NULL : (*igroup)[slotNum];
168168 }
169169
170 inline InstrGroup* getIGroup (CycleCount_t c) {
170 inline InstrGroup* getIGroup (CycleCount_t c) {
171171 if ((unsigned)c >= groups.size())
172172 groups.resize(c+1);
173173 if (groups[c] == NULL)
175175 return groups[c];
176176 }
177177
178 inline const InstrGroup* getIGroup (CycleCount_t c) const {
178 inline const InstrGroup* getIGroup (CycleCount_t c) const {
179179 assert((unsigned)c < groups.size());
180180 return groups[c];
181181 }
182182
183 inline CycleCount_t getStartTime (unsigned int nodeId) const {
183 inline CycleCount_t getStartTime (unsigned int nodeId) const {
184184 assert(nodeId < startTime.size());
185185 return startTime[nodeId];
186186 }
187187
188 unsigned int getNumInstructions() const {
188 unsigned int getNumInstructions() const {
189189 return numInstr;
190190 }
191191
192 inline void scheduleInstr (const SchedGraphNode* node,
193 unsigned int slotNum,
194 CycleCount_t cycle) {
192 inline void scheduleInstr (const SchedGraphNode* node,
193 unsigned int slotNum,
194 CycleCount_t cycle) {
195195 InstrGroup* igroup = this->getIGroup(cycle);
196196 if (!((*igroup)[slotNum] == NULL)) {
197197 std::cerr << "Slot already filled?\n";
206206 private:
207207 friend class ScheduleIterator;
208208 friend class ScheduleIterator;
209 /*ctor*/ InstrSchedule (); // Disable: DO NOT IMPLEMENT.
209 /*ctor*/ InstrSchedule (); // Disable: DO NOT IMPLEMENT.
210210 };
211211
212212 template
220220 InstrSchedule::InstrSchedule(unsigned int _nslots, unsigned int _numNodes)
221221 : nslots(_nslots),
222222 numInstr(0),
223 groups(2 * _numNodes / _nslots), // 2 x lower-bound for #cycles
224 startTime(_numNodes, (CycleCount_t) -1) // set all to -1
223 groups(2 * _numNodes / _nslots), // 2 x lower-bound for #cycles
224 startTime(_numNodes, (CycleCount_t) -1) // set all to -1
225225 {
226226 }
227227
231231 {
232232 for (unsigned c=0, NC=groups.size(); c < NC; c++)
233233 if (groups[c] != NULL)
234 delete groups[c]; // delete InstrGroup objects
234 delete groups[c]; // delete InstrGroup objects
235235 }
236236
237237
241241 ScheduleIterator<_NodeType>::skipToNextInstr()
242242 {
243243 while(cycleNum < S.groups.size() && S.groups[cycleNum] == NULL)
244 ++cycleNum; // skip cycles with no instructions
244 ++cycleNum; // skip cycles with no instructions
245245
246246 while (cycleNum < S.groups.size() &&
247 (*S.groups[cycleNum])[slotNum] == NULL)
247 (*S.groups[cycleNum])[slotNum] == NULL)
248248 {
249249 ++slotNum;
250250 if (slotNum == S.nslots) {
251251 ++cycleNum;
252252 slotNum = 0;
253253 while(cycleNum < S.groups.size() && S.groups[cycleNum] == NULL)
254 ++cycleNum; // skip cycles with no instructions
254 ++cycleNum; // skip cycles with no instructions
255255 }
256256 }
257257 }
259259 template
260260 inline
261261 ScheduleIterator<_NodeType>&
262 ScheduleIterator<_NodeType>::operator++() // Preincrement
262 ScheduleIterator<_NodeType>::operator++() // Preincrement
263263 {
264264 ++slotNum;
265265 if (slotNum == S.nslots) {
302302 DelaySlotInfo(const DelaySlotInfo &); // DO NOT IMPLEMENT
303303 void operator=(const DelaySlotInfo&); // DO NOT IMPLEMENT
304304 public:
305 /*ctor*/ DelaySlotInfo (const SchedGraphNode* _brNode,
306 unsigned _ndelays)
305 /*ctor*/ DelaySlotInfo (const SchedGraphNode* _brNode,
306 unsigned _ndelays)
307307 : brNode(_brNode), ndelays(_ndelays),
308308 delayedNodeCycle(0), delayedNodeSlotNum(0) {}
309309
310 inline unsigned getNumDelays () {
310 inline unsigned getNumDelays () {
311311 return ndelays;
312312 }
313313
315315 return delayNodeVec;
316316 }
317317
318 inline void addDelayNode (const SchedGraphNode* node) {
318 inline void addDelayNode (const SchedGraphNode* node) {
319319 delayNodeVec.push_back(node);
320320 assert(delayNodeVec.size() <= ndelays && "Too many delay slot instrs!");
321321 }
322322
323 inline void recordChosenSlot (CycleCount_t cycle, unsigned slotNum) {
323 inline void recordChosenSlot (CycleCount_t cycle, unsigned slotNum) {
324324 delayedNodeCycle = cycle;
325325 delayedNodeSlotNum = slotNum;
326326 }
327327
328 unsigned scheduleDelayedNode (SchedulingManager& S);
328 unsigned scheduleDelayedNode (SchedulingManager& S);
329329 };
330330
331331
347347 private:
348348 unsigned totalInstrCount;
349349 CycleCount_t curTime;
350 CycleCount_t nextEarliestIssueTime; // next cycle we can issue
350 CycleCount_t nextEarliestIssueTime; // next cycle we can issue
351351 // indexed by slot#
352352 std::vector > choicesForSlot;
353 std::vector choiceVec; // indexed by node ptr
354 std::vector numInClass; // indexed by sched class
355 std::vector<CycleCount_t> nextEarliestStartTime; // indexed by opCode
353 std::vector<const SchedGraphNode*> choiceVec; // indexed by node ptr
354 std::vector numInClass; // indexed by sched class
355 std::vector nextEarliestStartTime; // indexed by opCode
356356 hash_map delaySlotInfoForBranches;
357 // indexed by branch node ptr
357 // indexed by branch node ptr
358358
359359 public:
360360 SchedulingManager(const TargetMachine& _target, const SchedGraph* graph,
370370 // Simplify access to the machine instruction info
371371 //----------------------------------------------------------------------
372372
373 inline const TargetInstrInfo& getInstrInfo () const {
373 inline const TargetInstrInfo& getInstrInfo () const {
374374 return schedInfo.getInstrInfo();
375375 }
376376
378378 // Interface for checking and updating the current time
379379 //----------------------------------------------------------------------
380380
381 inline CycleCount_t getTime () const {
381 inline CycleCount_t getTime () const {
382382 return curTime;
383383 }
384384
385 inline CycleCount_t getEarliestIssueTime() const {
385 inline CycleCount_t getEarliestIssueTime() const {
386386 return nextEarliestIssueTime;
387387 }
388388
389 inline CycleCount_t getEarliestStartTimeForOp(MachineOpCode opCode) const {
389 inline CycleCount_t getEarliestStartTimeForOp(MachineOpCode opCode) const {
390390 assert(opCode < (int) nextEarliestStartTime.size());
391391 return nextEarliestStartTime[opCode];
392392 }
393393
394394 // Update current time to specified cycle
395 inline void updateTime (CycleCount_t c) {
395 inline void updateTime (CycleCount_t c) {
396396 curTime = c;
397397 schedPrio.updateTime(c);
398398 }
405405 // between choices for a single cycle
406406 //----------------------------------------------------------------------
407407
408 inline unsigned int getNumChoices () const {
408 inline unsigned int getNumChoices () const {
409409 return choiceVec.size();
410410 }
411411
412 inline unsigned getNumChoicesInClass (const InstrSchedClass& sc) const {
412 inline unsigned getNumChoicesInClass (const InstrSchedClass& sc) const {
413413 assert(sc < numInClass.size() && "Invalid op code or sched class!");
414414 return numInClass[sc];
415415 }
416416
417417 inline const SchedGraphNode* getChoice(unsigned int i) const {
418 // assert(i < choiceVec.size()); don't check here.
418 // assert(i < choiceVec.size()); don't check here.
419419 return choiceVec[i];
420420 }
421421
424424 return choicesForSlot[slotNum];
425425 }
426426
427 inline void addChoice (const SchedGraphNode* node) {
427 inline void addChoice (const SchedGraphNode* node) {
428428 // Append the instruction to the vector of choices for current cycle.
429429 // Increment numInClass[c] for the sched class to which the instr belongs.
430430 choiceVec.push_back(node);
433433 numInClass[sc]++;
434434 }
435435
436 inline void addChoiceToSlot (unsigned int slotNum,
437 const SchedGraphNode* node) {
436 inline void addChoiceToSlot (unsigned int slotNum,
437 const SchedGraphNode* node) {
438438 // Add the instruction to the choice set for the specified slot
439439 assert(slotNum < nslots);
440440 choicesForSlot[slotNum].insert(node);
441441 }
442442
443 inline void resetChoices () {
443 inline void resetChoices () {
444444 choiceVec.clear();
445445 for (unsigned int s=0; s < nslots; s++)
446446 choicesForSlot[s].clear();
452452 // Code to query and manage the partial instruction schedule so far
453453 //----------------------------------------------------------------------
454454
455 inline unsigned int getNumScheduled () const {
455 inline unsigned int getNumScheduled () const {
456456 return isched.getNumInstructions();
457457 }
458458
459 inline unsigned int getNumUnscheduled() const {
459 inline unsigned int getNumUnscheduled() const {
460460 return totalInstrCount - isched.getNumInstructions();
461461 }
462462
463 inline bool isScheduled (const SchedGraphNode* node) const {
463 inline bool isScheduled (const SchedGraphNode* node) const {
464464 return (isched.getStartTime(node->getNodeId()) >= 0);
465465 }
466466
467 inline void scheduleInstr (const SchedGraphNode* node,
468 unsigned int slotNum,
469 CycleCount_t cycle)
467 inline void scheduleInstr (const SchedGraphNode* node,
468 unsigned int slotNum,
469 CycleCount_t cycle)
470470 {
471471 assert(! isScheduled(node) && "Instruction already scheduled?");
472472
492492 //----------------------------------------------------------------------
493493
494494 inline DelaySlotInfo* getDelaySlotInfoForInstr(const SchedGraphNode* bn,
495 bool createIfMissing=false)
495 bool createIfMissing=false)
496496 {
497497 hash_map::const_iterator
498498 I = delaySlotInfoForBranches.find(bn);
514514
515515 /*ctor*/
516516 SchedulingManager::SchedulingManager(const TargetMachine& target,
517 const SchedGraph* graph,
518 SchedPriorities& _schedPrio)
517 const SchedGraph* graph,
518 SchedPriorities& _schedPrio)
519519 : nslots(target.getSchedInfo()->getMaxNumIssueTotal()),
520520 schedInfo(*target.getSchedInfo()),
521521 schedPrio(_schedPrio),
523523 totalInstrCount(graph->getNumNodes() - 2),
524524 nextEarliestIssueTime(0),
525525 choicesForSlot(nslots),
526 numInClass(target.getSchedInfo()->getNumSchedClasses(), 0), // set all to 0
526 numInClass(target.getSchedInfo()->getNumSchedClasses(), 0), // set all to 0
527527 nextEarliestStartTime(target.getInstrInfo()->getNumOpcodes(),
528 (CycleCount_t) 0) // set all to 0
528 (CycleCount_t) 0) // set all to 0
529529 {
530530 updateTime(0);
531531
539539
540540 void
541541 SchedulingManager::updateEarliestStartTimes(const SchedGraphNode* node,
542 CycleCount_t schedTime)
542 CycleCount_t schedTime)
543543 {
544544 if (schedInfo.numBubblesAfter(node->getOpcode()) > 0)
545545 { // Update next earliest time before which *nothing* can issue.
546546 nextEarliestIssueTime = std::max(nextEarliestIssueTime,
547 curTime + 1 + schedInfo.numBubblesAfter(node->getOpcode()));
547 curTime + 1 + schedInfo.numBubblesAfter(node->getOpcode()));
548548 }
549549
550550 const std::vector&
636636 if (!(I->getOpcode() == V9::NOP || I->getOpcode() == V9::PHI))
637637 ++numInstr;
638638 assert(S.isched.getNumInstructions() >= numInstr &&
639 "Lost some non-NOP instructions during scheduling!");
639 "Lost some non-NOP instructions during scheduling!");
640640
641641 if (S.isched.getNumInstructions() == 0)
642 return; // empty basic block!
642 return; // empty basic block!
643643
644644 // First find the dummy instructions at the start of the basic block
645645 MachineBasicBlock::iterator I = MBB.begin();
667667 //
668668 for (sg_succ_const_iterator SI = succ_begin(node); SI !=succ_end(node); ++SI)
669669 if (! (*SI)->isDummyNode()
670 && ! S.isScheduled(*SI)
671 && ! S.schedPrio.nodeIsReady(*SI))
670 && ! S.isScheduled(*SI)
671 && ! 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
682 if (succIsReady) // add the successor to the ready list
681
682 if (succIsReady) // add the successor to the ready list
683683 S.schedPrio.insertReady(*SI);
684684 }
685685 }
691691 // of chosen instructions can be issued in a single group.
692692 //
693693 // Return value:
694 // maxIssue : total number of feasible instructions
695 // S.choicesForSlot[i=0..nslots] : set of instructions feasible in slot i
694 // maxIssue : total number of feasible instructions
695 // S.choicesForSlot[i=0..nslots] : set of instructions feasible in slot i
696696 //
697697 static unsigned
698698 FindSlotChoices(SchedulingManager& S,
699 DelaySlotInfo*& getDelaySlotInfo)
699 DelaySlotInfo*& getDelaySlotInfo)
700700 {
701701 // initialize result vectors to empty
702702 S.resetChoices();
726726 while (S.getNumChoices() < S.nslots - startSlot) {
727727 const SchedGraphNode* nextNode=S.schedPrio.getNextHighest(S,S.getTime());
728728 if (nextNode == NULL)
729 break; // no more instructions for this cycle
729 break; // no more instructions for this cycle
730730
731731 if (S.getInstrInfo().getNumDelaySlots(nextNode->getOpcode()) > 0) {
732732 delaySlotInfo = S.getDelaySlotInfoForInstr(nextNode);
757757 }
758758
759759 if (indexForDelayedInstr < S.nslots)
760 break; // leave the rest for delay slots
760 break; // leave the rest for delay slots
761761 }
762762
763763 assert(S.getNumChoices() <= S.nslots);
764764 assert(! (indexForDelayedInstr < S.nslots &&
765 indexForBreakingNode < S.nslots) && "Cannot have both in a cycle");
765 indexForBreakingNode < S.nslots) && "Cannot have both in a cycle");
766766
767767 // Assign each chosen instruction to all possible slots for that instr.
768768 // But if only one instruction was chosen, put it only in the first
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 //
890890 bool foundLowerSlot = false;
891 nslotsToUse = S.nslots; // May be modified in the loop
891 nslotsToUse = S.nslots; // May be modified in the loop
892892 for (unsigned int s=startSlot; s < nslotsToUse; s++)
893893 if (S.schedInfo.instrCanUseSlot(opCode, s)) {
894894 if (breakingSlot < S.nslots && s < breakingSlot) {
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)
903 breakingSlot = INT_MAX; // disable breaking instr
903 breakingSlot = INT_MAX; // disable breaking instr
904904 }
905905
906906 // Assign the breaking instruction (if any) to a single slot
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.
931931 ChooseOneGroup(SchedulingManager& S)
932932 {
933933 assert(S.schedPrio.getNumReady() > 0
934 && "Don't get here without ready instructions.");
934 && "Don't get here without ready instructions.");
935935
936936 CycleCount_t firstCycle = S.getTime();
937937 DelaySlotInfo* getDelaySlotInfo = NULL;
10211021
10221022 static bool
10231023 NodeCanFillDelaySlot(const SchedulingManager& S,
1024 const SchedGraphNode* node,
1025 const SchedGraphNode* brNode,
1026 bool nodeIsPredecessor)
1024 const SchedGraphNode* node,
1025 const SchedGraphNode* brNode,
1026 bool nodeIsPredecessor)
10271027 {
10281028 assert(! node->isDummyNode());
10291029
10411041 for (SchedGraphNode::const_iterator EI = node->beginInEdges();
10421042 EI != node->endInEdges(); ++EI)
10431043 if (! ((SchedGraphNode*)(*EI)->getSrc())->isDummyNode()
1044 && mii.isLoad(((SchedGraphNode*)(*EI)->getSrc())->getOpcode())
1045 && (*EI)->getDepType() == SchedGraphEdge::CtrlDep)
1044 && mii.isLoad(((SchedGraphNode*)(*EI)->getSrc())->getOpcode())
1045 && (*EI)->getDepType() == SchedGraphEdge::CtrlDep)
10461046 return false;
10471047
10481048 // Finally, if the instruction precedes the branch, we make sure the
10711071
10721072 static void
10731073 MarkNodeForDelaySlot(SchedulingManager& S,
1074 SchedGraph* graph,
1075 SchedGraphNode* node,
1076 const SchedGraphNode* brNode,
1077 bool nodeIsPredecessor)
1074 SchedGraph* graph,
1075 SchedGraphNode* node,
1076 const SchedGraphNode* brNode,
1077 bool nodeIsPredecessor)
10781078 {
10791079 if (nodeIsPredecessor) {
10801080 // If node is in the same basic block (i.e., precedes brNode),
11141114 for (sg_pred_iterator P = pred_begin(brNode);
11151115 P != pred_end(brNode) && sdelayNodeVec.size() < ndelays; ++P)
11161116 if (! (*P)->isDummyNode() &&
1117 ! mii.isNop((*P)->getOpcode()) &&
1118 NodeCanFillDelaySlot(S, *P, brNode, /*pred*/ true))
1117 ! mii.isNop((*P)->getOpcode()) &&
1118 NodeCanFillDelaySlot(S, *P, brNode, /*pred*/ true))
11191119 {
11201120 if (mii.maxLatency((*P)->getOpcode()) > 1)
11211121 mdelayNodeVec.push_back(*P);
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 =
12401240 //
12411241 static void
12421242 ChooseInstructionsForDelaySlots(SchedulingManager& S, MachineBasicBlock &MBB,
1243 SchedGraph *graph)
1243 SchedGraph *graph)
12441244 {
12451245 const TargetInstrInfo& mii = S.getInstrInfo();
12461246
13001300 {
13011301 assert(delayedNodeSlotNum < S.nslots && "Illegal slot for branch");
13021302 assert(S.isched.getInstr(delayedNodeSlotNum, delayedNodeCycle) == NULL
1303 && "Slot for branch should be empty");
1303 && "Slot for branch should be empty");
13041304
13051305 unsigned int nextSlot = delayedNodeSlotNum;
13061306 CycleCount_t nextTime = delayedNodeCycle;
13491349 nextTime++;
13501350 }
13511351 } while (S.isched.getInstr(nextSlot, nextTime) != NULL);
1352
1352
13531353 S.scheduleInstr(delayNodeVec[i], nextSlot, nextTime);
13541354 break;
13551355 }
13631363 //
13641364 static inline bool
13651365 ConflictsWithChoices(const SchedulingManager& S,
1366 MachineOpCode opCode)
1366 MachineOpCode opCode)
13671367 {
13681368 // Check if the instruction must issue by itself, and some feasible
13691369 // choices have already been made for this cycle
13931393
13941394 static inline bool
13951395 ViolatesMinimumGap(const SchedulingManager& S,
1396 MachineOpCode opCode,
1397 const CycleCount_t inCycle)
1396 MachineOpCode opCode,
1397 const CycleCount_t inCycle)
13981398 {
13991399 return (inCycle < S.getEarliestStartTimeForOp(opCode));
14001400 }
14101410
14111411 bool
14121412 instrIsFeasible(const SchedulingManager& S,
1413 MachineOpCode opCode)
1413 MachineOpCode opCode)
14141414 {
14151415 // skip the instruction if it cannot be issued due to issue restrictions
14161416 // caused by previously issued instructions
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";
7171 // Method: SchedGraphNode Destructor
7272 //
7373 // Description:
74 // Free memory allocated by the SchedGraphNode object.
74 // Free memory allocated by the SchedGraphNode object.
7575 //
7676 // Notes:
77 // Do not delete the edges here. The base class will take care of that.
78 // Only handle subclass specific stuff here (where currently there is
79 // none).
77 // Do not delete the edges here. The base class will take care of that.
78 // Only handle subclass specific stuff here (where currently there is
79 // none).
8080 //
8181 SchedGraphNode::~SchedGraphNode() {
8282 }
9393 // Method: SchedGraph Destructor
9494 //
9595 // Description:
96 // This method deletes memory allocated by the SchedGraph object.
96 // This method deletes memory allocated by the SchedGraph object.
9797 //
9898 // Notes:
99 // Do not delete the graphRoot or graphLeaf here. The base class handles
100 // that bit of work.
99 // Do not delete the graphRoot or graphLeaf here. The base class handles
100 // that bit of work.
101101 //
102102 SchedGraph::~SchedGraph() {
103103 for (const_iterator I = begin(); I != end(); ++I)
138138
139139
140140 void SchedGraph::addCDEdges(const TerminatorInst* term,
141 const TargetMachine& target) {
141 const TargetMachine& target) {
142142 const TargetInstrInfo& mii = *target.getInstrInfo();
143143 MachineCodeForInstruction &termMvec = MachineCodeForInstruction::get(term);
144144
149149 ! mii.isReturn(termMvec[first]->getOpcode()))
150150 ++first;
151151 assert(first < termMvec.size() &&
152 "No branch instructions for terminator? Ok, but weird!");
152 "No branch instructions for terminator? Ok, but weird!");
153153 if (first == termMvec.size())
154154 return;
155155
170170 assert(brNode && "No node for instr generated for branch/ret?");
171171 (void) new SchedGraphEdge(brNode, toNode, SchedGraphEdge::CtrlDep,
172172 SchedGraphEdge::NonDataDep, 0);
173 break; // only one incoming edge is enough
173 break; // only one incoming edge is enough
174174 }
175175 }
176176
193193
194194 SchedGraphNode* fromNode = getGraphNodeForInstr(I);
195195 if (fromNode == NULL)
196 continue; // dummy instruction, e.g., PHI
196 continue; // dummy instruction, e.g., PHI
197197
198198 (void) new SchedGraphEdge(fromNode, firstBrNode,
199199 SchedGraphEdge::CtrlDep,
240240 // latency does not otherwise matter (true dependences enforce that).
241241 //
242242 void SchedGraph::addMemEdges(const std::vector& memNodeVec,
243 const TargetMachine& target) {
243 const TargetMachine& target) {
244244 const TargetInstrInfo& mii = *target.getInstrInfo();
245245
246246 // Instructions in memNodeVec are in execution order within the basic block,
272272 // like with control dependences.
273273 //
274274 void SchedGraph::addCallDepEdges(const std::vector& callDepNodeVec,
275 const TargetMachine& target) {
275 const TargetMachine& target) {
276276 const TargetInstrInfo& mii = *target.getInstrInfo();
277277
278278 // Instructions in memNodeVec are in execution order within the basic block,
282282 if (mii.isCall(callDepNodeVec[ic]->getOpcode())) {
283283 // Add SG_CALL_REF edges from all preds to this instruction.
284284 for (unsigned jc=0; jc < ic; jc++)
285 (void) new SchedGraphEdge(callDepNodeVec[jc], callDepNodeVec[ic],
286 SchedGraphEdge::MachineRegister,
287 MachineIntRegsRID, 0);
285 (void) new SchedGraphEdge(callDepNodeVec[jc], callDepNodeVec[ic],
286 SchedGraphEdge::MachineRegister,
287 MachineIntRegsRID, 0);
288288
289289 // And do the same from this instruction to all successors.
290290 for (unsigned jc=ic+1; jc < NC; jc++)
291 (void) new SchedGraphEdge(callDepNodeVec[ic], callDepNodeVec[jc],
292 SchedGraphEdge::MachineRegister,
293 MachineIntRegsRID, 0);
291 (void) new SchedGraphEdge(callDepNodeVec[ic], callDepNodeVec[jc],
292 SchedGraphEdge::MachineRegister,
293 MachineIntRegsRID, 0);
294294 }
295295
296296 #ifdef CALL_DEP_NODE_VEC_CANNOT_WORK
330330
331331
332332 void SchedGraph::addMachineRegEdges(RegToRefVecMap& regToRefVecMap,
333 const TargetMachine& target) {
333 const TargetMachine& target) {
334334 // This code assumes that two registers with different numbers are
335335 // not aliased!
336336 //
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,
381381 // We do not consider other uses because we are not building use-use deps.
382382 //
383383 void SchedGraph::addEdgesForValue(SchedGraphNode* refNode,
384 const RefVec& defVec,
385 const Value* defValue,
386 bool refNodeIsDef,
387 bool refNodeIsUse,
388 const TargetMachine& target) {
384 const RefVec& defVec,
385 const Value* defValue,
386 bool refNodeIsDef,
387 bool refNodeIsUse,
388 const TargetMachine& target) {
389389 // Add true or output dep edges from all def nodes before refNode in BB.
390390 // Add anti or output dep edges to all def nodes after refNode.
391391 for (RefVec::const_iterator I=defVec.begin(), E=defVec.end(); I != E; ++I) {
414414
415415
416416 void SchedGraph::addEdgesForInstruction(const MachineInstr& MI,
417 const ValueToDefVecMap& valueToDefVecMap,
418 const TargetMachine& target) {
417 const ValueToDefVecMap& valueToDefVecMap,
418 const TargetMachine& target) {
419419 SchedGraphNode* node = getGraphNodeForInstr(&MI);
420420 if (node == NULL)
421421 return;
442442 case MachineOperand::MO_UnextendedImmed:
443443 case MachineOperand::MO_PCRelativeDisp:
444444 case MachineOperand::MO_ConstantPoolIndex:
445 break; // nothing to do for immediate fields
445 break; // nothing to do for immediate fields
446446
447447 default:
448448 assert(0 && "Unknown machine operand type in SchedGraph builder");
467467
468468
469469 void SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target,
470 SchedGraphNode* node,
471 std::vector& memNodeVec,
472 std::vector& callDepNodeVec,
473 RegToRefVecMap& regToRefVecMap,
474 ValueToDefVecMap& valueToDefVecMap) {
470 SchedGraphNode* node,
471 std::vector& memNodeVec,
472 std::vector& callDepNodeVec,
473 RegToRefVecMap& regToRefVecMap,
474 ValueToDefVecMap& valueToDefVecMap) {
475475 const TargetInstrInfo& mii = *target.getInstrInfo();
476476
477477 MachineOpCode opCode = node->getOpcode();
549549
550550
551551 void SchedGraph::buildNodesForBB(const TargetMachine& target,
552 MachineBasicBlock& MBB,
553 std::vector& memNodeVec,
554 std::vector& callDepNodeVec,
555 RegToRefVecMap& regToRefVecMap,
556 ValueToDefVecMap& valueToDefVecMap) {
552 MachineBasicBlock& MBB,
553 std::vector& memNodeVec,
554 std::vector& callDepNodeVec,
555 RegToRefVecMap& regToRefVecMap,
556 ValueToDefVecMap& valueToDefVecMap) {
557557 const TargetInstrInfo& mii = *target.getInstrInfo();
558558
559559 // Build graph nodes for each VM instruction and gather def/use info.
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
653653 // class SchedGraphSet
654654 //
655655 SchedGraphSet::SchedGraphSet(const Function* _function,
656 const TargetMachine& target) :
656 const TargetMachine& target) :
657657 function(_function) {
658658 buildGraphsForMethod(function, target);
659659 }
678678
679679
680680 void SchedGraphSet::buildGraphsForMethod(const Function *F,
681 const TargetMachine& target) {
681 const TargetMachine& target) {
682682 MachineFunction &MF = MachineFunction::get(F);
683683 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
684684 addGraph(new SchedGraph(*I, target));
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:
3737
3838
3939 SchedGraphNode(unsigned nodeId, MachineBasicBlock *mbb, int indexInBB,
40 const TargetMachine& Target);
40 const TargetMachine& Target);
4141 ~SchedGraphNode();
4242
43 friend class SchedGraph; // give access for ctor and dtor
44 friend class SchedGraphEdge; // give access for adding edges
43 friend class SchedGraph; // give access for ctor and dtor
44 friend class SchedGraphEdge; // give access for adding edges
4545
4646 public:
4747
9494 }
9595
9696 private:
97 friend class SchedGraphSet; // give access to ctor
98
99 inline void noteGraphNodeForInstr (const MachineInstr* minstr,
100 SchedGraphNode* node) {
97 friend class SchedGraphSet; // give access to ctor
98
99 inline void noteGraphNodeForInstr (const MachineInstr* minstr,
100 SchedGraphNode* node) {
101101 assert((*this)[minstr] == NULL);
102102 (*this)[minstr] = node;
103103 }
108108 void buildGraph(const TargetMachine& target);
109109
110110 void buildNodesForBB(const TargetMachine& target,MachineBasicBlock &MBB,
111 std::vector& memNV,
112 std::vector& callNV,
113 RegToRefVecMap& regToRefVecMap,
114 ValueToDefVecMap& valueToDefVecMap);
111 std::vector& memNV,
112 std::vector& callNV,
113 RegToRefVecMap& regToRefVecMap,
114 ValueToDefVecMap& valueToDefVecMap);
115115
116116
117117 void findDefUseInfoAtInstr(const TargetMachine& target, SchedGraphNode* node,
118 std::vector& memNV,
119 std::vector& callNV,
120 RegToRefVecMap& regToRefVecMap,
121 ValueToDefVecMap& valueToDefVecMap);
118 std::vector& memNV,
119 std::vector& callNV,
120 RegToRefVecMap& regToRefVecMap,
121 ValueToDefVecMap& valueToDefVecMap);
122122
123123 void addEdgesForInstruction(const MachineInstr& minstr,
124 const ValueToDefVecMap& valueToDefVecMap,
125 const TargetMachine& target);
124 const ValueToDefVecMap& valueToDefVecMap,
125 const TargetMachine& target);
126126
127127 void addCDEdges(const TerminatorInst* term, const TargetMachine& target);
128128
129129 void addMemEdges(const std::vector& memNod,
130 const TargetMachine& target);
130 const TargetMachine& target);
131131
132132 void addCallCCEdges(const std::vector& memNod,
133 MachineBasicBlock& bbMvec,
134 const TargetMachine& target);
133 MachineBasicBlock& bbMvec,
134 const TargetMachine& target);
135135
136136 void addCallDepEdges(const std::vector& callNV,
137 const TargetMachine& target);
137 const TargetMachine& target);
138138
139139 void addMachineRegEdges(RegToRefVecMap& regToRefVecMap,
140 const TargetMachine& target);
140 const TargetMachine& target);
141141
142142 void addEdgesForValue(SchedGraphNode* refNode, const RefVec& defVec,
143 const Value* defValue, bool refNodeIsDef,
144 bool refNodeIsDefAndUse,
145 const TargetMachine& target);
143 const Value* defValue, bool refNodeIsDef,
144 bool refNodeIsDefAndUse,
145 const TargetMachine& target);
146146
147147 void addDummyEdges();
148148
2424 // class SchedGraphEdge
2525 //
2626 SchedGraphEdge::SchedGraphEdge(SchedGraphNodeCommon* _src,
27 SchedGraphNodeCommon* _sink,
28 SchedGraphEdgeDepType _depType,
29 unsigned int _depOrderType,
30 int _minDelay)
27 SchedGraphNodeCommon* _sink,
28 SchedGraphEdgeDepType _depType,
29 unsigned int _depOrderType,
30 int _minDelay)
3131 : src(_src), sink(_sink), depType(_depType), depOrderType(_depOrderType),
3232 minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()), val(NULL) {
3333
3838 }
3939
4040 SchedGraphEdge::SchedGraphEdge(SchedGraphNodeCommon* _src,
41 SchedGraphNodeCommon* _sink,
42 const Value* _val,
43 unsigned int _depOrderType,
44 int _minDelay)
41 SchedGraphNodeCommon* _sink,
42 const Value* _val,
43 unsigned int _depOrderType,
44 int _minDelay)
4545 : src(_src), sink(_sink), depType(ValueDep), depOrderType(_depOrderType),
4646 minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()), val(_val) {
4747 iteDiff=0;
5151 }
5252
5353 SchedGraphEdge::SchedGraphEdge(SchedGraphNodeCommon* _src,
54 SchedGraphNodeCommon* _sink,
55 unsigned int _regNum,
56 unsigned int _depOrderType,
57 int _minDelay)
54 SchedGraphNodeCommon* _sink,
55 unsigned int _regNum,
56 unsigned int _depOrderType,
57 int _minDelay)
5858 : src(_src), sink(_sink), depType(MachineRegister),
5959 depOrderType(_depOrderType),
6060 minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()),
6666 }
6767
6868 SchedGraphEdge::SchedGraphEdge(SchedGraphNodeCommon* _src,
69 SchedGraphNodeCommon* _sink,
70 ResourceId _resourceId,
71 int _minDelay)
69 SchedGraphNodeCommon* _sink,
70 ResourceId _resourceId,
71 int _minDelay)
7272 : src(_src), sink(_sink), depType(MachineResource), depOrderType(NonDataDep),
7373 minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()),
7474 resourceId(_resourceId) {
124124
125125
126126 void SchedGraphCommon::eraseIncomingEdges(SchedGraphNodeCommon* node,
127 bool addDummyEdges) {
127 bool addDummyEdges) {
128128 // Delete and disconnect all in-edges for the node
129129 for (SchedGraphNodeCommon::iterator I = node->beginInEdges();
130130 I != node->endInEdges(); ++I) {
133133 delete *I;
134134
135135 if (addDummyEdges && srcNode != getRoot() &&
136 srcNode->beginOutEdges() == srcNode->endOutEdges()) {
136 srcNode->beginOutEdges() == srcNode->endOutEdges()) {
137137
138138 // srcNode has no more out edges, so add an edge to dummy EXIT node
139139 assert(node != getLeaf() && "Adding edge that was just removed?");
140140 (void) new SchedGraphEdge(srcNode, getLeaf(),
141 SchedGraphEdge::CtrlDep,
142 SchedGraphEdge::NonDataDep, 0);
141 SchedGraphEdge::CtrlDep,
142 SchedGraphEdge::NonDataDep, 0);
143143 }
144144 }
145145
147147 }
148148
149149 void SchedGraphCommon::eraseOutgoingEdges(SchedGraphNodeCommon* node,
150 bool addDummyEdges) {
150 bool addDummyEdges) {
151151 // Delete and disconnect all out-edges for the node
152152 for (SchedGraphNodeCommon::iterator I = node->beginOutEdges();
153153 I != node->endOutEdges(); ++I) {
156156 delete *I;
157157
158158 if (addDummyEdges &&
159 sinkNode != getLeaf() &&
160 sinkNode->beginInEdges() == sinkNode->endInEdges()) {
159 sinkNode != getLeaf() &&
160 sinkNode->beginInEdges() == sinkNode->endInEdges()) {
161161
162162 //sinkNode has no more in edges, so add an edge from dummy ENTRY node
163163 assert(node != getRoot() && "Adding edge that was just removed?");
164164 (void) new SchedGraphEdge(getRoot(), sinkNode,
165 SchedGraphEdge::CtrlDep,
166 SchedGraphEdge::NonDataDep, 0);
165 SchedGraphEdge::CtrlDep,
166 SchedGraphEdge::NonDataDep, 0);
167167 }
168168 }
169169
171171 }
172172
173173 void SchedGraphCommon::eraseIncidentEdges(SchedGraphNodeCommon* node,
174 bool addDummyEdges) {
175 this->eraseIncomingEdges(node, addDummyEdges);
176 this->eraseOutgoingEdges(node, addDummyEdges);
174 bool addDummyEdges) {
175 this->eraseIncomingEdges(node, addDummyEdges);
176 this->eraseOutgoingEdges(node, addDummyEdges);
177177 }
178178
179179 } // End llvm namespace
2727
2828 std::ostream &operator<<(std::ostream &os, const NodeDelayPair* nd) {
2929 return os << "Delay for node " << nd->node->getNodeId()
30 << " = " << (long)nd->delay << "\n";
30 << " = " << (long)nd->delay << "\n";
3131 }
3232
3333
117117
118118 void
119119 SchedPriorities::issuedReadyNodeAt(CycleCount_t curTime,
120 const SchedGraphNode* node) {
120 const SchedGraphNode* node) {
121121 candsAsHeap.removeNode(node);
122122 candsAsSet.erase(node);
123123 mcands.clear(); // ensure reset choices is called before any more choices
155155
156156 inline int
157157 SchedPriorities::chooseByRule1(std::vector& mcands) {
158 return (mcands.size() == 1)? 0 // only one choice exists so take it
159 : -1; // -1 indicates multiple choices
158 return (mcands.size() == 1)? 0 // only one choice exists so take it
159 : -1; // -1 indicates multiple choices
160160 }
161161
162162 inline int
164164 assert(mcands.size() >= 1 && "Should have at least one candidate here.");
165165 for (unsigned i=0, N = mcands.size(); i < N; i++)
166166 if (instructionHasLastUse(methodLiveVarInfo,
167 candsAsHeap.getNode(mcands[i])))
167 candsAsHeap.getNode(mcands[i])))
168168 return i;
169169 return -1;
170170 }
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();
186186
187187 const SchedGraphNode*
188188 SchedPriorities::getNextHighest(const SchedulingManager& S,
189 CycleCount_t curTime) {
189 CycleCount_t curTime) {
190190 int nextIdx = -1;
191191 const SchedGraphNode* nextChoice = NULL;
192192
194194 findSetWithMaxDelay(mcands, S);
195195
196196 while (nextIdx < 0 && mcands.size() > 0) {
197 nextIdx = chooseByRule1(mcands); // rule 1
197 nextIdx = chooseByRule1(mcands); // rule 1
198198
199199 if (nextIdx == -1)
200200 nextIdx = chooseByRule2(mcands); // rule 2
203203 nextIdx = chooseByRule3(mcands); // rule 3
204204
205205 if (nextIdx == -1)
206 nextIdx = 0; // default to first choice by delays
206 nextIdx = 0; // default to first choice by delays
207207
208208 // We have found the next best candidate. Check if it ready in
209209 // the current cycle, and if it is feasible.
230230
231231 void
232232 SchedPriorities::findSetWithMaxDelay(std::vector& mcands,
233 const SchedulingManager& S)
233 const SchedulingManager& S)
234234 {
235235 if (mcands.size() == 0 && nextToTry != candsAsHeap.end())
236236 { // out of choices at current maximum delay;
238238 candIndex next = nextToTry;
239239 CycleCount_t maxDelay = candsAsHeap.getDelay(next);
240240 for (; next != candsAsHeap.end()
241 && candsAsHeap.getDelay(next) == maxDelay; ++next)
242 mcands.push_back(next);
241 && candsAsHeap.getDelay(next) == maxDelay; ++next)
242 mcands.push_back(next);
243243
244244 nextToTry = next;
245245
257257
258258 bool
259259 SchedPriorities::instructionHasLastUse(FunctionLiveVarInfo &LVI,
260 const SchedGraphNode* graphNode) {
260 const SchedGraphNode* graphNode) {
261261 const MachineInstr *MI = graphNode->getMachineInstr();
262262
263263 hash_map::const_iterator
8383
8484 inline unsigned size() const { return _size; }
8585
86 const SchedGraphNode* getNode (const_iterator i) const { return (*i)->node; }
87 CycleCount_t getDelay(const_iterator i) const { return (*i)->delay;}
88
89 inline void makeHeap() {
86 const SchedGraphNode* getNode (const_iterator i) const { return (*i)->node; }
87 CycleCount_t getDelay(const_iterator i) const { return (*i)->delay;}
88
89 inline void makeHeap() {
9090 // make_heap(begin(), end(), NDPLessThan);
9191 }
9292
93 inline iterator findNode(const SchedGraphNode* node) {
93 inline iterator findNode(const SchedGraphNode* node) {
9494 for (iterator I=begin(); I != end(); ++I)
9595 if (getNode(I) == node)
96 return I;
96 return I;
9797 return end();
9898 }
9999
100 inline void removeNode (const SchedGraphNode* node) {
100 inline void removeNode (const SchedGraphNode* node) {
101101 iterator ndpPtr = findNode(node);
102102 if (ndpPtr != end())
103103 {
104 delete *ndpPtr;
105 erase(ndpPtr);
106 --_size;
104 delete *ndpPtr;
105 erase(ndpPtr);
106 --_size;
107107 }
108108 };
109109
110 void insert(const SchedGraphNode* node, CycleCount_t delay) {
110 void insert(const SchedGraphNode* node, CycleCount_t delay) {
111111 NodeDelayPair* ndp = new NodeDelayPair(node, delay);
112112 if (_size == 0 || front()->delay < delay)
113113 push_front(ndp);
114114 else
115115 {
116 iterator I=begin();
117 for ( ; I != end() && getDelay(I) >= delay; ++I)
118 ;
119 std::list::insert(I, ndp);
116 iterator I=begin();
117 for ( ; I != end() && getDelay(I) >= delay; ++I)
118 ;
119 std::list::insert(I, ndp);
120120 }
121121 _size++;
122122 }
134134
135135
136136 // This must be called before scheduling begins.
137 void initialize ();
138
139 CycleCount_t getTime () const { return curTime; }
140 CycleCount_t getEarliestReadyTime () const { return earliestReadyTime; }
141 unsigned getNumReady () const { return candsAsHeap.size(); }
142 bool nodeIsReady (const SchedGraphNode* node) const {
137 void initialize ();
138
139 CycleCount_t getTime () const { return curTime; }
140 CycleCount_t getEarliestReadyTime () const { return earliestReadyTime; }
141 unsigned getNumReady () const { return candsAsHeap.size(); }
142 bool nodeIsReady (const SchedGraphNode* node) const {
143143 return (candsAsSet.find(node) != candsAsSet.end());
144144 }
145145
146 void issuedReadyNodeAt (CycleCount_t curTime,
147 const SchedGraphNode* node);
148
149 void insertReady (const SchedGraphNode* node);
150
151 void updateTime (CycleCount_t /*unused*/);
152
153 const SchedGraphNode* getNextHighest (const SchedulingManager& S,
154 CycleCount_t curTime);
155 // choose next highest priority instr
146 void issuedReadyNodeAt (CycleCount_t curTime,
147 const SchedGraphNode* node);
148
149 void insertReady (const SchedGraphNode* node);
150
151 void updateTime (CycleCount_t /*unused*/);
152
153 const SchedGraphNode* getNextHighest (const SchedulingManager& S,
154 CycleCount_t curTime);
155 // choose next highest priority instr
156156
157157 private:
158158 typedef NodeHeap::iterator candIndex;
166166 std::vector nodeEarliestUseVec;
167167 std::vector earliestReadyTimeForNode;
168168 CycleCount_t earliestReadyTime;
169 NodeHeap candsAsHeap; // candidate nodes, ready to go
169 NodeHeap candsAsHeap; // candidate nodes, ready to go
170170 hash_set candsAsSet; //same entries as candsAsHeap,
171 // but as set for fast lookup
171 // but as set for fast lookup
172172 std::vector mcands; // holds pointers into cands
173 candIndex nextToTry; // next cand after the last
174 // one tried in this cycle
175
176 int chooseByRule1 (std::vector& mcands);
177 int chooseByRule2 (std::vector& mcands);
178 int chooseByRule3 (std::vector& mcands);
179
180 void findSetWithMaxDelay (std::vector& mcands,
181 const SchedulingManager& S);
182
183 void computeDelays (const SchedGraph* graph);
184
185 void initializeReadyHeap (const SchedGraph* graph);
186
187 bool instructionHasLastUse (FunctionLiveVarInfo& LVI,
188 const SchedGraphNode* graphNode);
173 candIndex nextToTry; // next cand after the last
174 // one tried in this cycle
175
176 int chooseByRule1 (std::vector& mcands);
177 int chooseByRule2 (std::vector& mcands);
178 int chooseByRule3 (std::vector& mcands);
179
180 void findSetWithMaxDelay (std::vector& mcands,
181 const SchedulingManager& S);
182
183 void computeDelays (const SchedGraph* graph);
184
185 void initializeReadyHeap (const SchedGraph* graph);
186
187 bool instructionHasLastUse (FunctionLiveVarInfo& LVI,
188 const SchedGraphNode* graphNode);
189189
190190 // NOTE: The next two return references to the actual vector entries.
191191 // Use the following two if you don't need to modify the value.
192 CycleCount_t& getNodeDelayRef (const SchedGraphNode* node) {
192 CycleCount_t& getNodeDelayRef (const SchedGraphNode* node) {
193193 assert(node->getNodeId() < nodeDelayVec.size());
194194 return nodeDelayVec[node->getNodeId()];
195195 }
5353 for (MachineInstr::const_val_op_iterator OpI = MI->begin(), OpE = MI->end();
5454 OpI != OpE; ++OpI)
5555 if (OpI.isDef()) // add to Defs if this operand is a def
56 addDef(*OpI);
56 addDef(*OpI);
5757
5858 // do for implicit operands as well
5959 for (unsigned i = 0; i < MI->getNumImplicitRefs(); ++i)
6060 if (MI->getImplicitOp(i).isDef())
61 addDef(MI->getImplicitRef(i));
61 addDef(MI->getImplicitRef(i));
6262
6363 // iterate over MI operands to find uses
6464 for (MachineInstr::const_val_op_iterator OpI = MI->begin(), OpE = MI->end();
6666 const Value *Op = *OpI;
6767
6868 if (isa(Op))
69 continue; // don't process labels
69 continue; // don't process labels
7070
7171 if (OpI.isUse()) { // add to Uses only if this operand is a use
7272 //
7878 // Put Phi operands in UseSet for the incoming edge, not node.
7979 // They must not "hide" later defs, and must be handled specially
8080 // during set propagation over the CFG.
81 if (MI->getOpcode() == V9::PHI) { // for a phi node
81 if (MI->getOpcode() == V9::PHI) { // for a phi node
8282 const Value *ArgVal = Op;
83 const BasicBlock *PredBB = cast(*++OpI); // next ptr is BB
84
85 PredToEdgeInSetMap[PredBB].insert(ArgVal);
86
87 if (DEBUG_LV >= LV_DEBUG_Verbose)
88 std::cerr << " - phi operand " << RAV(ArgVal) << " came from BB "
83 const BasicBlock *PredBB = cast(*++OpI); // next ptr is BB
84
85 PredToEdgeInSetMap[PredBB].insert(ArgVal);
86
87 if (DEBUG_LV >= LV_DEBUG_Verbose)
88 std::cerr << " - phi operand " << RAV(ArgVal) << " came from BB "
8989 << RAV(PredBB) << "\n";
90 } // if( IsPhi )
90 } // if( IsPhi )
9191 else {
9292 // It is not a Phi use: add to regular use set and remove later defs.
9393 addUse(Op);
101101 const Value *Op = MI->getImplicitRef(i);
102102
103103 if (Op->getType() == Type::LabelTy) // don't process labels
104 continue;
104 continue;
105105
106106 if (MI->getImplicitOp(i).isUse())
107 addUse(Op);
107 addUse(Op);
108108 }
109109 } // for all machine instructions
110110 }
111111
112112
113
113
114114 //-----------------------------------------------------------------------------
115115 // To add an operand which is a def
116116 //-----------------------------------------------------------------------------
207207
208208 // if the predec POID is lower than mine
209209 if (PredLVBB->getPOId() <= POID)
210 needAnotherIt = true;
210 needAnotherIt = true;
211211 }
212212 } // for
213213
7070
7171 void SparcV9FunctionInfo::CalculateArgSize() {
7272 maxOptionalArgsSize = ComputeMaxOptionalArgsSize(MF.getTarget(),
73 MF.getFunction(),
73 MF.getFunction(),
7474 maxOptionalNumArgs);
7575 staticStackSize = maxOptionalArgsSize + 176;
7676 }
7777
7878 int
7979 SparcV9FunctionInfo::computeOffsetforLocalVar(const Value* val,
80 unsigned &getPaddedSize,
81 unsigned sizeToUse)
80 unsigned &getPaddedSize,
81 unsigned sizeToUse)
8282 {
8383 if (sizeToUse == 0) {
8484 // All integer types smaller than ints promote to 4 byte integers.
9191
9292 bool growUp;
9393 int firstOffset = MF.getTarget().getFrameInfo()->getFirstAutomaticVarOffset(MF,
94 growUp);
94 growUp);
9595 int offset = growUp? firstOffset + getAutomaticVarsSize()
9696 : firstOffset - (getAutomaticVarsSize() + sizeToUse);
9797
157157 : firstOffset - (currentTmpValuesSize + size);
158158
159159 int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp,
160 align);
160 align);
161161 size += abs(aligned - offset); // include alignment padding in size
162162
163163 incrementTmpAreaSize(size); // update "current" size of tmp area
3232 hash_set constantsForConstPool;
3333 hash_map offsets;
3434
35 unsigned staticStackSize;
36 unsigned automaticVarsSize;
37 unsigned regSpillsSize;
38 unsigned maxOptionalArgsSize;
39 unsigned maxOptionalNumArgs;
40 unsigned currentTmpValuesSize;
41 unsigned maxTmpValuesSize;
35 unsigned staticStackSize;
36 unsigned automaticVarsSize;
37 unsigned regSpillsSize;
38 unsigned maxOptionalArgsSize;
39 unsigned maxOptionalNumArgs;
40 unsigned currentTmpValuesSize;
41 unsigned maxTmpValuesSize;
4242 bool compiledAsLeaf;
4343 bool spillsAreaFrozen;
4444 bool automaticVarsAreaFrozen;
157157
158158 void MappingInfo::byteVector::dumpAssembly (std::ostream &Out) {
159159 for (iterator i = begin (), e = end (); i != e; ++i)
160 Out << ".byte " << (int)*i << "\n";
160 Out << ".byte " << (int)*i << "\n";
161161 }
162162
163163 static void writePrologue (std::ostream &Out, const std::string &comment,
164 const std::string &symName) {
164 const std::string &symName) {
165165 // Prologue:
166166 // Output a comment describing the object.
167167 Out << "!" << comment << "\n";
3636 public:
3737 void outByte (unsigned char b) { bytes.push_back (b); }
3838 MappingInfo (std::string Comment, std::string SymbolPrefix,
39 unsigned FunctionNumber) : comment(Comment),
40 symbolPrefix(SymbolPrefix), functionNumber(FunctionNumber) {}
39 unsigned FunctionNumber) : comment(Comment),
40 symbolPrefix(SymbolPrefix), functionNumber(FunctionNumber) {}
4141 void dumpAssembly (std::ostream &Out);
4242 unsigned char *getBytes (unsigned &length) {
43 length = bytes.size(); return &bytes[0];
43 length = bytes.size(); return &bytes[0];
4444 }
4545 };
4646
3030
3131 Statistic<> NoDeps("depanalyzer-nodeps", "Number of dependences eliminated");
3232 Statistic<> NumDeps("depanalyzer-deps",
33 "Number of dependences could not eliminate");
33 "Number of dependences could not eliminate");
3434 Statistic<> AdvDeps("depanalyzer-advdeps",
35 "Number of dependences using advanced techniques");
35 "Number of dependences using advanced techniques");
3636
3737 bool DependenceAnalyzer::runOnFunction(Function &F) {
3838 AA = &getAnalysis();
4343 }
4444
4545 static RegisterAnalysisX("depanalyzer",
46 "Dependence Analyzer");
46 "Dependence Analyzer");
4747
4848 // - Get inter and intra dependences between loads and stores
4949 //
5656 // further (Step 4)
5757 // Step 4: do advanced analysis
5858 void DependenceAnalyzer::AnalyzeDeps(Value *val, Value *val2, bool valLoad,
59 bool val2Load,
60 std::vector &deps,
61 BasicBlock *BB,
62 bool srcBeforeDest) {
59 bool val2Load,
60 std::vector &deps,
61 BasicBlock *BB,
62 bool srcBeforeDest) {
6363
6464 bool loopInvariant = true;
6565
7575 //If Loop invariant, let AA decide
7676 if(loopInvariant) {
7777 if(AA->alias(val, (unsigned)TD->getTypeSize(val->getType()),
78 val2,(unsigned)TD->getTypeSize(val2->getType()))
78 val2,(unsigned)TD->getTypeSize(val2->getType()))
7979 != AliasAnalysis::NoAlias) {
8080 createDep(deps, valLoad, val2Load, srcBeforeDest);
8181 }
101101 Value *GPop = GP->getOperand(0);
102102 Value *GP2op = GP2->getOperand(0);
103103 int alias = AA->alias(GPop, (unsigned)TD->getTypeSize(GPop->getType()),
104 GP2op,(unsigned)TD->getTypeSize(GP2op->getType()));
104 GP2op,(unsigned)TD->getTypeSize(GP2op->getType()));
105105
106106
107107 if(alias == AliasAnalysis::MustAlias) {
120120
121121 // advancedDepAnalysis - Do advanced data dependence tests
122122 void DependenceAnalyzer::advancedDepAnalysis(GetElementPtrInst *gp1,
123 GetElementPtrInst *gp2,
124 bool valLoad,
125 bool val2Load,
126 std::vector &deps,
127 bool srcBeforeDest) {
123 GetElementPtrInst *gp2,
124 bool valLoad,
125 bool val2Load,
126 std::vector &deps,
127 bool srcBeforeDest) {
128128
129129 //Check if both GEPs are in a simple form: 3 ops, constant 0 as second arg
130130 if(gp1->getNumOperands() != 3 || gp2->getNumOperands() != 3) {
137137 if(Constant *c1 = dyn_cast(gp1->getOperand(1)))
138138 if(Constant *c2 = dyn_cast(gp2->getOperand(1)))
139139 if(c1->isNullValue() && c2->isNullValue())
140 GPok = true;
140 GPok = true;
141141
142142 if(!GPok) {
143143 createDep(deps, valLoad, val2Load, srcBeforeDest);
229229 // Create dependences once its determined these two instructions
230230 // references the same memory
231231 void DependenceAnalyzer::createDep(std::vector &deps,
232 bool valLoad, bool val2Load,
233 bool srcBeforeDest, int diff) {
232 bool valLoad, bool val2Load,
233 bool srcBeforeDest, int diff) {
234234
235235 //If the source instruction occurs after the destination instruction
236236 //(execution order), then this dependence is across iterations
268268
269269 //Get Dependence Info for a pair of Instructions
270270 DependenceResult DependenceAnalyzer::getDependenceInfo(Instruction *inst1,
271 Instruction *inst2,
272 bool srcBeforeDest) {
271 Instruction *inst2,
272 bool srcBeforeDest) {
273273 std::vector deps;
274274
275275 DEBUG(std::cerr << "Inst1: " << *inst1 << "\n");
283283
284284 if(StoreInst *stInst = dyn_cast(inst2))
285285 AnalyzeDeps(ldInst->getOperand(0), stInst->getOperand(1),
286 true, false, deps, ldInst->getParent(), srcBeforeDest);
286 true, false, deps, ldInst->getParent(), srcBeforeDest);
287287 }
288288 else if(StoreInst *stInst = dyn_cast(inst1)) {
289289
290290 if(LoadInst *ldInst = dyn_cast(inst2))
291291 AnalyzeDeps(stInst->getOperand(1), ldInst->getOperand(0), false, true,
292 deps, ldInst->getParent(), srcBeforeDest);
292 deps, ldInst->getParent(), srcBeforeDest);
293293
294294 else if(StoreInst *stInst2 = dyn_cast(inst2))
295295 AnalyzeDeps(stInst->getOperand(1), stInst2->getOperand(1), false, false,
296 deps, stInst->getParent(), srcBeforeDest);
296 deps, stInst->getParent(), srcBeforeDest);
297297 }
298298 else
299299 assert(0 && "Expected a load or a store\n");
2121 #include
2222
2323 namespace llvm {
24
24
2525
2626 //class to represent a dependence
2727 struct Dependence {
4848
4949
5050 class DependenceAnalyzer : public FunctionPass {
51
51
5252
5353 AliasAnalysis *AA;
5454 TargetData *TD;
5555 ScalarEvolution *SE;
5656
57 void advancedDepAnalysis(GetElementPtrInst *gp1, GetElementPtrInst *gp2,
58 bool valLoad, bool val2Load,
59 std::vector &deps, bool srcBeforeDest);
57 void advancedDepAnalysis(GetElementPtrInst *gp1, GetElementPtrInst *gp2,
58 bool valLoad, bool val2Load,
59 std::vector &deps, bool srcBeforeDest);
6060
61 void AnalyzeDeps(Value *val, Value *val2, bool val1Load, bool val2Load,
62 std::vector &deps, BasicBlock *BB,
63 bool srcBeforeDest);
64
65 void createDep(std::vector &deps, bool valLoad, bool val2Load,
66 bool srcBeforeDest, int diff = 0);
61 void AnalyzeDeps(Value *val, Value *val2, bool val1Load, bool val2Load,
62 std::vector &deps, BasicBlock *BB,
63 bool srcBeforeDest);
64
65 void createDep(std::vector &deps, bool valLoad, bool val2Load,
66 bool srcBeforeDest, int diff = 0);
6767
6868 public:
6969 DependenceAnalyzer() { AA = 0; TD = 0; SE = 0; }
7979 }
8080
8181 //get dependence info
82 DependenceResult getDependenceInfo(Instruction *inst1, Instruction *inst2,
83 bool srcBeforeDest);
82 DependenceResult getDependenceInfo(Instruction *inst1, Instruction *inst2,
83 bool srcBeforeDest);
8484
8585 };
8686
3232 if (schedule[cycle].size() < numIssue) {
3333 //Now check if all the resources in their respective cycles are available
3434 if(resourcesFree(node, cycle, II)) {
35 //Insert to preserve dependencies
36 addToSchedule(cycle,node);
37 DEBUG(std::cerr << "Found spot in map, and there is an issue slot\n");
38 return false;
35 //Insert to preserve dependencies
36 addToSchedule(cycle,node);
37 DEBUG(std::cerr << "Found spot in map, and there is an issue slot\n");
38 return false;
3939 }
4040 }
4141 }
8080 if(resourceNumPerCycle[cycle].count(resourceNum)) {
8181 int maxRes = CPUResource::getCPUResource(resourceNum)->maxNumUsers;
8282 if(resourceNumPerCycle[cycle][resourceNum] >= maxRes)
83 isFree = false;
83 isFree = false;
8484 }
8585 }
8686
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
140 //Get Resource to check its availability
141 int resourceNum = resources[i][j];
142
143 DEBUG(std::cerr << "Attempting to schedule Resource Num: " << resourceNum << " in cycle: " << currentCycle << "\n");
144
145 success = resourceAvailable(resourceNum, currentCycle);
146
147 if(!success)
148 break;
149
139
140 //Get Resource to check its availability
141 int resourceNum = resources[i][j];
142
143 DEBUG(std::cerr << "Attempting to schedule Resource Num: " << resourceNum << " in cycle: " << currentCycle << "\n");
144
145 success = resourceAvailable(resourceNum, currentCycle);
146
147 if(!success)
148 break;
149
150150 }
151151
152152 if(!success)
153 break;
153 break;
154154
155155 //Increase cycle
156156 currentCycle++;
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) {
174 int resourceNum = resources[i][j];
175 useResource(resourceNum, currentCycle);
174 int resourceNum = resources[i][j];
175 useResource(resourceNum, currentCycle);
176176 }
177177 currentCycle++;
178178 }
204204 int count = 0;
205205 for(int i = index; i <= (schedule.rbegin()->first); i+=II) {
206206 if(schedule.count(i)) {
207 for(std::vector::iterator I = schedule[i].begin(),
208 E = schedule[i].end(); I != E; ++I) {
209 //Check if its a branch
210 assert(!(*I)->isBranch() && "Branch should not be schedule!");
211
212 tempKernel.push_back(std::make_pair(*I, count));
213 maxSN = std::max(maxSN, count);
214
215 }
207 for(std::vector::iterator I = schedule[i].begin(),
208 E = schedule[i].end(); I != E; ++I) {
209 //Check if its a branch
210 assert(!(*I)->isBranch() && "Branch should not be schedule!");
211
212 tempKernel.push_back(std::make_pair(*I, count));
213 maxSN = std::max(maxSN, count);
214
215 }
216216 }
217217 ++count;
218218 }
230230 for(std::map::iterator N = indVar.begin(), NE = indVar.end(); N != NE; ++N) {
231231
232232
233 if(N->second < I->first->getIndex())
234 tmpMap[N->second] = (MachineInstr*) N->first;
233 if(N->second < I->first->getIndex())
234 tmpMap[N->second] = (MachineInstr*) N->first;
235235 }
236236
237237 //Add to kernel, and delete from indVar
238238 for(std::map::iterator N = tmpMap.begin(), NE = tmpMap.end(); N != NE; ++N) {
239 kernel.push_back(std::make_pair(N->second, 0));
240 indVar.erase(N->second);
239 kernel.push_back(std::make_pair(N->second, 0));
240 indVar.erase(N->second);
241241 }
242242 }
243243
277277 const MachineOperand &mOp = inst->getOperand(i);
278278 if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
279279 if(def == mOp.getVRegValue()) {
280 if(P->second >= stage)
281 return false;
282 else
283 return true;
280 if(P->second >= stage)
281 return false;
282 else
283 return true;
284284 }
285285 }
286286 }
301301
302302 os << "Kernel:\n";
303303 for(std::vector >::const_iterator I = kernel.begin(),
304 E = kernel.end(); I != E; ++I)
304 E = kernel.end(); I != E; ++I)
305305 os << "Node: " << *(I->first) << " Stage: " << I->second << "\n";
306306 }
307307
2727 std::map > resourceNumPerCycle;
2828
2929 //Check if all resources are free
30 bool resourcesFree(MSchedGraphNode*, int, int II);
30 bool resourcesFree(MSchedGraphNode*, int, int II);
3131 bool resourceAvailable(int resourceNum, int cycle);
3232 void useResource(int resourceNum, int cycle);
3333
3232 if (schedule[cycle].size() < numIssue) {
3333 //Now check if all the resources in their respective cycles are available
3434 if(resourcesFree(node, cycle, II)) {
35 //Insert to preserve dependencies
36 addToSchedule(cycle,node);
37 DEBUG(std::cerr << "Found spot in map, and there is an issue slot\n");
38 return false;
35 //Insert to preserve dependencies
36 addToSchedule(cycle,node);
37 DEBUG(std::cerr << "Found spot in map, and there is an issue slot\n");
38 return false;
3939 }
4040 }
4141 }
8080 if(resourceNumPerCycle[cycle].count(resourceNum)) {
8181 int maxRes = CPUResource::getCPUResource(resourceNum)->maxNumUsers;
8282 if(resourceNumPerCycle[cycle][resourceNum] >= maxRes)
83 isFree = false;
83 isFree = false;
8484 }
8585 }
8686
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
140 //Get Resource to check its availability
141 int resourceNum = resources[i][j];
142
143 DEBUG(std::cerr << "Attempting to schedule Resource Num: " << resourceNum << " in cycle: " << currentCycle << "\n");
144
145 success = resourceAvailable(resourceNum, currentCycle);
146
147 if(!success)
148 break;
149
139
140 //Get Resource to check its availability
141 int resourceNum = resources[i][j];
142
143 DEBUG(std::cerr << "Attempting to schedule Resource Num: " << resourceNum << " in cycle: " << currentCycle << "\n");
144
145 success = resourceAvailable(resourceNum, currentCycle);
146
147 if(!success)
148 break;
149
150150 }
151151
152152 if(!success)
153 break;
153 break;
154154
155155 //Increase cycle
156156 currentCycle++;
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) {
174 int resourceNum = resources[i][j];
175 useResource(resourceNum, currentCycle);
174 int resourceNum = resources[i][j];
175 useResource(resourceNum, currentCycle);
176176 }
177177 currentCycle++;
178178 }
204204 int count = 0;
205205 for(int i = index; i <= (schedule.rbegin()->first); i+=II) {
206206 if(schedule.count(i)) {
207 for(std::vector::iterator I = schedule[i].begin(),
208 E = schedule[i].end(); I != E; ++I) {
209 //Check if its a branch
210 assert(!(*I)->isBranch() && "Branch should not be schedule!");
211
212 tempKernel.push_back(std::make_pair(*I, count));
213 maxSN = std::max(maxSN, count);
214
215 }
207 for(std::vector::iterator I = schedule[i].begin(),
208 E = schedule[i].end(); I != E; ++I) {
209 //Check if its a branch
210 assert(!(*I)->isBranch() && "Branch should not be schedule!");
211
212 tempKernel.push_back(std::make_pair(*I, count));
213 maxSN = std::max(maxSN, count);
214
215 }
216216 }
217217 ++count;
218218 }
230230 for(std::map::iterator N = indVar.begin(), NE = indVar.end(); N != NE; ++N) {
231231
232232
233 if(N->second < I->first->getIndex())
234 tmpMap[N->second] = (MachineInstr*) N->first;
233 if(N->second < I->first->getIndex())
234 tmpMap[N->second] = (MachineInstr*) N->first;
235235 }
236236
237237 //Add to kernel, and delete from indVar
238238 for(std::map::iterator N = tmpMap.begin(), NE = tmpMap.end(); N != NE; ++N) {
239 kernel.push_back(std::make_pair(N->second, 0));
240 indVar.erase(N->second);
239 kernel.push_back(std::make_pair(N->second, 0));
240 indVar.erase(N->second);
241241 }
242242 }
243243
246246 //assert(I->second == 0 && "Predicate node must be from current iteration\n");
247247 std::vector otherInstrs = I->first->getOtherInstrs();
248248 for(std::vector::iterator O = otherInstrs.begin(), OE = otherInstrs.end(); O != OE; ++O) {
249 kernel.push_back(std::make_pair((MachineInstr*) *O, I->second));
249 kernel.push_back(std::make_pair((MachineInstr*) *O, I->second));
250250 }
251251 }
252252
284284 const MachineOperand &mOp = inst->getOperand(i);
285285 if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
286286 if(def == mOp.getVRegValue()) {
287 if(P->second >= stage)
288 return false;
289 else
290 return true;
287 if(P->second >= stage)
288 return false;
289 else
290 return true;
291291 }
292292 }
293293 }
308308
309309 os << "Kernel:\n";
310310 for(std::vector >::const_iterator I = kernel.begin(),
311 E = kernel.end(); I != E; ++I)
311 E = kernel.end(); I != E; ++I)
312312 os << "Node: " << *(I->first) << " Stage: " << I->second << "\n";
313313 }
314314
2727 std::map > resourceNumPerCycle;
2828
2929 //Check if all resources are free
30 bool resourcesFree(MSchedGraphSBNode*, int, int II);
30 bool resourcesFree(MSchedGraphSBNode*, int, int II);
3131 bool resourceAvailable(int resourceNum, int cycle);
3232 void useResource(int resourceNum, int cycle);
3333
3232
3333 //MSchedGraphNode constructor
3434 MSchedGraphNode::MSchedGraphNode(const MachineInstr* inst,
35 MSchedGraph *graph, unsigned idx,
36 unsigned late, bool isBranch)
35 MSchedGraph *graph, unsigned idx,
36 unsigned late, bool isBranch)
3737 : Inst(inst), Parent(graph), index(idx), latency(late),
3838 isBranchInstr(isBranch) {
3939
7575 //Get the iteration difference for the edge from this node to its successor
7676 unsigned MSchedGraphNode::getIteDiff(MSchedGraphNode *succ) {
7777 for(std::vector::iterator I = Successors.begin(),
78 E = Successors.end();
78 E = Successors.end();
7979 I != E; ++I) {
8080 if(I->getDest() == succ)
8181 return I->getIteDiff();
8989 //return the edge the corresponds to this in edge
9090 int count = 0;
9191 for(MSchedGraphNode::succ_iterator I = pred->succ_begin(),
92 E = pred->succ_end();
92 E = pred->succ_end();
9393 I != E; ++I) {
9494 if(*I == this)
9595 return count;
110110 //Dtermine if pred is a predecessor of this node
111111 bool MSchedGraphNode::isPredecessor(MSchedGraphNode *pred) {
112112 if(std::find( Predecessors.begin(), Predecessors.end(),
113 pred) != Predecessors.end())
113 pred) != Predecessors.end())
114114 return true;
115115 else
116116 return false;
118118
119119 //Add a node to the graph
120120 void MSchedGraph::addNode(const MachineInstr *MI,
121 MSchedGraphNode *node) {
121 MSchedGraphNode *node) {
122122
123123 //Make sure node does not already exist
124124 assert(GraphMap.find(MI) == GraphMap.end()
125 && "New MSchedGraphNode already exists for this instruction");
125 && "New MSchedGraphNode already exists for this instruction");
126126
127127 GraphMap[MI] = node;
128128 }
148148 //is a special case in Modulo Scheduling. We only want to deal with
149149 //the body of the loop.
150150 MSchedGraph::MSchedGraph(const MachineBasicBlock *bb,
151 const TargetMachine &targ,
152 std::map &ignoreInstrs,
153 DependenceAnalyzer &DA,
154 std::map &machineTollvm)
151 const TargetMachine &targ,
152 std::map &ignoreInstrs,
153 DependenceAnalyzer &DA,
154 std::map &machineTollvm)
155155 : Target(targ) {
156156
157157 //Make sure BB is not null,
171171 //is a special case in Modulo Scheduling. We only want to deal with
172172 //the body of the loop.
173173 MSchedGraph::MSchedGraph(std::vector &bbs,
174 const TargetMachine &targ,
175 std::map &ignoreInstrs,
176 DependenceAnalyzer &DA,
177 std::map &machineTollvm)
174 const TargetMachine &targ,
175 std::map &ignoreInstrs,
176 DependenceAnalyzer &DA,
177 std::map &machineTollvm)
178178 : BBs(bbs), Target(targ) {
179179
180180 //Make sure there is at least one BB and it is not null,
190190
191191 //Copies the graph and keeps a map from old to new nodes
192192 MSchedGraph::MSchedGraph(const MSchedGraph &G,
193 std::map &newNodes)
193 std::map &newNodes)
194194 : Target(G.Target) {
195195
196196 BBs = G.BBs;
198198 std::map oldToNew;
199199 //Copy all nodes
200200 for(MSchedGraph::const_iterator N = G.GraphMap.begin(),
201 NE = G.GraphMap.end(); N != NE; ++N) {
201 NE = G.GraphMap.end(); N != NE; ++N) {
202202
203203 MSchedGraphNode *newNode = new MSchedGraphNode(*(N->second));
204204 oldToNew[&*(N->second)] = newNode;
271271 }
272272 //Experimental code to add edges from the branch to all nodes dependent upon it.
273273 void hasPath(MSchedGraphNode *node, std::set &visited,
274 std::set &branches, MSchedGraphNode *startNode,
275 std::set > &newEdges ) {
274 std::set &branches, MSchedGraphNode *startNode,
275 std::set > &newEdges ) {
276276
277277 visited.insert(node);
278278 DEBUG(std::cerr << "Visiting: " << *node << "\n");
286286 //only visit if we have not already
287287 else if(!visited.count(dest)) {
288288 if(edge->getIteDiff() == 0)
289 hasPath(dest, visited, branches, startNode, newEdges);}
289 hasPath(dest, visited, branches, startNode, newEdges);}
290290
291291 }
292292
301301 I != E; ++I) {
302302 if(I->second->isBranch())
303303 if(I->second->hasPredecessors())
304 branches.insert(I->second);
304 branches.insert(I->second);
305305 }
306306
307307 //See if there is a path first instruction to the branches, if so, add an
317317 unsigned min = GraphMap.size();
318318 if(newEdges.size() == 1) {
319319 ((newEdges.begin())->first)->addOutEdge(((newEdges.begin())->second),
320 MSchedGraphEdge::BranchDep,
321 MSchedGraphEdge::NonDataDep, 1);
320 MSchedGraphEdge::BranchDep,
321 MSchedGraphEdge::NonDataDep, 1);
322322 }
323323 else {
324324
330330 DEBUG(std::cerr << "Branch Edge from: " << *(I->first) << " to " << *(I->second) << "\n");
331331
332332 // if(I->second->getIndex() <= min) {
333 start = I->first;
334 end = I->second;
335 //min = I->second->getIndex();
336 //}
337 start->addOutEdge(end,
338 MSchedGraphEdge::BranchDep,
339 MSchedGraphEdge::NonDataDep, 1);
333 start = I->first;
334 end = I->second;
335 //min = I->second->getIndex();
336 //}
337 start->addOutEdge(end,
338 MSchedGraphEdge::BranchDep,
339 MSchedGraphEdge::NonDataDep, 1);
340340 }
341341 }
342342 }
344344
345345 //Add edges between the nodes
346346 void MSchedGraph::buildNodesAndEdges(std::map &ignoreInstrs,
347 DependenceAnalyzer &DA,
348 std::map &machineTollvm) {
347 DependenceAnalyzer &DA,
348 std::map &machineTollvm) {
349349
350350
351351 //Get Machine target information for calculating latency
360360 unsigned index = 0;
361361
362362 for(std::vector::iterator B = BBs.begin(),
363 BE = BBs.end(); B != BE; ++B) {
363 BE = BBs.end(); B != BE; ++B) {
364364
365365 const MachineBasicBlock *BB = *B;
366366
367367 //Loop over instructions in MBB and add nodes and edges
368368 for (MachineBasicBlock::const_iterator MI = BB->begin(), e = BB->end();
369 MI != e; ++MI) {
369 MI != e; ++MI) {
370370
371371 //Ignore indvar instructions
372372 if(ignoreInstrs.count(MI)) {
373 ++index;
374 continue;
373 ++index;
374 continue;
375375 }
376376
377377 //Get each instruction of machine basic block, get the delay
385385 //Check if subsequent instructions can be issued before
386386 //the result is ready, if so use min delay.
387387 if(MTI->hasResultInterlock(MIopCode))
388 delay = MTI->minLatency(MIopCode);
388 delay = MTI->minLatency(MIopCode);
389389 else
390390 #endif
391 //Get delay
392 delay = MTI->maxLatency(opCode);
391 //Get delay
392 delay = MTI->maxLatency(opCode);
393393
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))
397 continue;
397 continue;
398398
399399 //Sparc BE does not use PHI opcode, so assert on this case
400400 assert(opCode != TargetInstrInfo::PHI && "Did not expect PHI opcode");
403403
404404 //We want to flag the branch node to treat it special
405405 if(MTI->isBranch(opCode))
406 isBranch = true;
406 isBranch = true;
407407
408408 //Node is created and added to the graph automatically
409409 MSchedGraphNode *node = new MSchedGraphNode(MI, this, index, delay,
410 isBranch);
410 isBranch);
411411
412412 DEBUG(std::cerr << "Created Node: " << *node << "\n");
413413
414414 //Check OpCode to keep track of memory operations to add memory
415415 //dependencies later.
416416 if(MTI->isLoad(opCode) || MTI->isStore(opCode))
417 memInstructions.push_back(node);
417 memInstructions.push_back(node);
418418
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) {
423 //Get Operand
424 const MachineOperand &mOp = MI->getOperand(i);
425
426 //Check if it has an allocated register
427 if(mOp.hasAllocatedReg()) {
428 int regNum = mOp.getReg();
429
430 if(regNum != SparcV9::g0) {
431 //Put into our map
432 regNumtoNodeMap[regNum].push_back(std::make_pair(i, node));
433 }
434 continue;
435 }
436
437
438 //Add virtual registers dependencies
439 //Check if any exist in the value map already and create dependencies
440 //between them.
441 if(mOp.getType() == MachineOperand::MO_VirtualRegister
442 || mOp.getType() == MachineOperand::MO_CCRegister) {
443
444 //Make sure virtual register value is not null
445 assert((mOp.getVRegValue() != NULL) && "Null value is defined");
446
447 //Check if this is a read operation in a phi node, if so DO NOT PROCESS
448 if(mOp.isUse() && (opCode == TargetInstrInfo::PHI)) {
449 DEBUG(std::cerr << "Read Operation in a PHI node\n");
450 continue;
451 }
452
453 if (const Value* srcI = mOp.getVRegValue()) {
454
455 //Find value in the map
456 std::map >::iterator V
457 = valuetoNodeMap.find(srcI);
458
459 //If there is something in the map already, add edges from
460 //those instructions
461 //to this one we are processing
462 if(V != valuetoNodeMap.end()) {
463 addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), phiInstrs);
464
465 //Add to value map
466 V->second.push_back(std::make_pair(i,node));
467 }
468 //Otherwise put it in the map
469 else
470 //Put into value map
471 valuetoNodeMap[mOp.getVRegValue()].push_back(std::make_pair(i, node));
472 }
473 }
423 //Get Operand
424 const MachineOperand &mOp = MI->getOperand(i);
425
426 //Check if it has an allocated register
427 if(mOp.hasAllocatedReg()) {
428 int regNum = mOp.getReg();
429
430 if(regNum != SparcV9::g0) {
431 //Put into our map
432 regNumtoNodeMap[regNum].push_back(std::make_pair(i, node));
433 }
434 continue;
435 }
436
437
438 //Add virtual registers dependencies
439 //Check if any exist in the value map already and create dependencies
440 //between them.
441 if(mOp.getType() == MachineOperand::MO_VirtualRegister
442 || mOp.getType() == MachineOperand::MO_CCRegister) {
443
444 //Make sure virtual register value is not null
445 assert((mOp.getVRegValue() != NULL) && "Null value is defined");
446
447 //Check if this is a read operation in a phi node, if so DO NOT PROCESS
448 if(mOp.isUse() && (opCode == TargetInstrInfo::PHI)) {
449 DEBUG(std::cerr << "Read Operation in a PHI node\n");
450 continue;
451 }
452
453 if (const Value* srcI = mOp.getVRegValue()) {
454
455 //Find value in the map
456 std::map >::iterator V
457 = valuetoNodeMap.find(srcI);
458
459 //If there is something in the map already, add edges from
460 //those instructions
461 //to this one we are processing
462 if(V != valuetoNodeMap.end()) {
463 addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), phiInstrs);
464
465 //Add to value map
466 V->second.push_back(std::make_pair(i,node));
467 }
468 //Otherwise put it in the map
469 else
470 //Put into value map
471 valuetoNodeMap[mOp.getVRegValue()].push_back(std::make_pair(i, node));
472 }
473 }
474474 }
475475 ++index;
476476 }
479479 //phiInstr list to process
480480 const BasicBlock *llvm_bb = BB->getBasicBlock();
481481 for(BasicBlock::const_iterator I = llvm_bb->begin(), E = llvm_bb->end();
482 I != E; ++I) {
482 I != E; ++I) {
483483 if(const PHINode *PN = dyn_cast(I)) {
484 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(PN);
485 for (unsigned j = 0; j < tempMvec.size(); j++) {
486 if(!ignoreInstrs.count(tempMvec[j])) {
487 DEBUG(std::cerr << "Inserting phi instr into map: " << *tempMvec[j] << "\n");
488 phiInstrs.push_back((MachineInstr*) tempMvec[j]);
489 }
490 }
484 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(PN);
485 for (unsigned j = 0; j < tempMvec.size(); j++) {
486 if(!ignoreInstrs.count(tempMvec[j])) {
487 DEBUG(std::cerr << "Inserting phi instr into map: " << *tempMvec[j] << "\n");
488 phiInstrs.push_back((MachineInstr*) tempMvec[j]);
489 }
490 }
491491 }
492492
493493 }
497497
498498 //Finally deal with PHI Nodes and Value*
499499 for(std::vector::iterator I = phiInstrs.begin(),
500 E = phiInstrs.end(); I != E; ++I) {
500 E = phiInstrs.end(); I != E; ++I) {
501501
502502 //Get Node for this instruction
503503 std::map::iterator X;
504504 X = find(*I);
505505
506506 if(X == GraphMap.end())
507 continue;
507 continue;
508508
509509 MSchedGraphNode *node = X->second;
510510
512512
513513 //Loop over operands for this instruction and add value edges
514514 for(unsigned i=0; i < (*I)->getNumOperands(); ++i) {
515 //Get Operand
516 const MachineOperand &mOp = (*I)->getOperand(i);
517 if((mOp.getType() == MachineOperand::MO_VirtualRegister
518 || mOp.getType() == MachineOperand::MO_CCRegister) && mOp.isUse()) {
519
520 //find the value in the map
521 if (const Value* srcI = mOp.getVRegValue()) {
522
523 //Find value in the map
524 std::map >::iterator V
525 = valuetoNodeMap.find(srcI);
526
527 //If there is something in the map already, add edges from
528 //those instructions
529 //to this one we are processing
530 if(V != valuetoNodeMap.end()) {
531 addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(),
532 phiInstrs, 1);
533 }
534 }
535 }
515 //Get Operand
516 const MachineOperand &mOp = (*I)->getOperand(i);
517 if((mOp.getType() == MachineOperand::MO_VirtualRegister
518 || mOp.getType() == MachineOperand::MO_CCRegister) && mOp.isUse()) {
519
520 //find the value in the map
521 if (const Value* srcI = mOp.getVRegValue()) {
522
523 //Find value in the map
524 std::map >::iterator V
525 = valuetoNodeMap.find(srcI);
526
527 //If there is something in the map already, add edges from
528 //those instructions
529 //to this one we are processing
530 if(V != valuetoNodeMap.end()) {
531 addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(),
532 phiInstrs, 1);
533 }
534 }
535 }
536536 }
537537 }
538538 }
539